ts快速入门

文章目录

  • 一、运行环境
    • 1、线上Playground
    • 2、VSCode 编辑器
    • 3、Code Runner 插件
    • 4、ts-node
  • 二、声明
    • 1、变量声明
    • 2、常量声明
    • 3、类型推断
  • 三、常用数据类型
    • 1、number
    • 2、string
    • 3、boolean
    • 4、数组
    • 5、对象
  • 四、函数
    • 1、函数声明语法
    • 2、参数详解
      • (1)特殊语法(可选参数、默认参数)
      • (2)特殊类型(联合类型、任意类型)
    • 3、返回值详解
      • (1)特殊类型
      • (2)类型推断
    • 4、函数声明特殊语法
      • (1)匿名函数
      • (2)箭头函数
  • 五、类
    • 1、概述
    • 2、语法说明
      • (1)类的定义
      • (2)对象创建
      • (3)静态成员(静态属性和静态方法)
    • 3、继承
    • 4、访问修饰符
  • 六、接口
    • 1、概述
    • 2、语法说明
    • 3、多态
    • 4、接口的作用
    • 5、TS 中的接口的特殊性
  • 七、枚举
    • 1、概述
    • 2、语法说明
    • 3、赋值
  • 八、模块化
    • 1、概述
    • 2、语法说明
    • 3、避免命名冲突
    • 4、默认导入导出


尚硅谷视频学习笔记

一、运行环境

1、线上Playground

TypeScript提供了一个线上的 Playground 供练习使用,地址为https://www.typescriptlang.org/zh/play。

在这里插入图片描述

2、VSCode 编辑器

VSCode是一款轻量级、开源且功能丰富的集成开发环境(IDE),支持多种编程语言,具有强大的插件系统。下载地址为:https://code.visualstudio.com/

3、Code Runner 插件

Code Runner是一款在VSCode中使用的插件,它提供了简便的代码执行功能,支持多种编程语言,使开发者能够快速运行和调试代码片段

在这里插入图片描述

4、ts-node

ts-node是一个 TypeScript 的运行环境,它允许我们直接运行 TypeScript 代码。ts-node的安装和运行依赖于Node.js环境,因此在安装ts-node之前,我们需要准备好Node.js环境。

Node.js环境准备好后,终端执行以下命令来安装ts-node

npm install -g ts-node

安装好 ts-node 后就可以在vscode中新建 .ts 文件编写Typescript代码并运行了。

在这里插入图片描述

二、声明

1、变量声明

  • let用于声明变量,赋值后可以修改
let a:number = 160;

2、常量声明

  • const用于声明常量,赋值后便不能再修改
const b:number = 200;

3、类型推断

  • 如果一个变量或常量的声明包含了初始值,TS 便可以根据初始值进行类型推断,此时我们就可以不显式指定其类型,例如:
let c = 60;
console.log(typeof c); //number

三、常用数据类型

1、number

number表示数字,包括整数和浮点数,例如: 100、-33 、2.5、-3.9

let a :number = 100
let b :number = -33
let c :number = 2.5
let d :number = -3.9

2、string

string表示字符串,例如: 你好、hello

let a:string = '你好'
let b:string = 'hello'

3、boolean

boolean表示布尔值,可选值为:true、false

let isOpen:boolean = true
let isDone:boolean = false

4、数组

数组类型定义由两部分组成,元素类型[],例如 number[] 表示数字数组,string[] 表示字符串数组,数组类型的变量可由数组字面量——[item1,item2,item3]进行初始化。

let a: number[] = []

let b: string[] = ['你好', 'hello']

5、对象

在TS中,对象(object)是一种一系列由属性名称和属性值组成的数据结构,例如姓名:'张三', 年龄:10, 性别:'男'。对象类型的声明需要包含所有属性的名称及类型,例如{name: string, age: number, gender: string},对象类型的变量可以通过对象字面量——{name:‘张三’, age:10, gender:‘男’}进行初始化。

let person: {name:string, age:number, gender:string} = {name:'张三', age:10, gender:'男'};

四、函数

1、函数声明语法

在这里插入图片描述

2、参数详解

(1)特殊语法(可选参数、默认参数)

  • 可选参数:可选参数通过参数名后的?进行标识,如以下案例中的gender?参数。
  • :调用函数时,未传递可选参数,则该参数的值为undefined
function getPersonInfo(name: string, age: number, gender?: string): string {
    if (gender === undefined) {
        gender = '未知'
    }
    return `name:${name},age:${age},gender:${gender}`;
}

let p1 = getPersonInfo('zhagnsan', 10, '男')
let p2 = getPersonInfo('lisi', 15);
console.log(p1);
console.log(p2);
  • 默认参数:可在函数的参数列表为参数指定默认值,如以下案例中的gender: string='未知'参数。
function getPersonInfo(name: string, age: number, gender: string='未知'): string {
    return `name:${name},age:${age},gender:${gender}`;
}

let p1 = getPersonInfo('zhagnsan', 10, '男')
let p2 = getPersonInfo('lisi', 15);
console.log(p1);
console.log(p2);

(2)特殊类型(联合类型、任意类型)

  • 联合类型:一个函数可能用于处理不同类型的值,这种情况可以使用联合类型,例如以下案例中的message: number | string
function printNumberOrString(message: number | string) {
  console.log(message)
}

printNumberOrString('a')
printNumberOrString(1)
  • 任意类型:若函数需要处理任意类型的值,则可以使用any类型,例如以下案例中的message: any
function print(message:any) {
  console.log(message)
}

print('a')
print(1)
print(true)

3、返回值详解

(1)特殊类型

若函数没有返回值,则可以使用void作为返回值类型,其含义为

function test(): void {
    console.log('hello');
}

(2)类型推断

函数的返回值类型根据函数内容推断出来,因此可以省略不写

function test() {
    console.log('hello');
}

function sum(a: number, b: number) {
    return a + b;
}

4、函数声明特殊语法

(1)匿名函数

匿名函数的语法结构简洁,特别适用于简单且仅需一次性使用的场景。function(){}

let numbers: number[] = [1, 2, 3, 4, 5]
numbers.forEach(function (number) {
    console.log(number);
})

注意:匿名函数能够根据上下文推断出参数类型,因此参数类型可以省略。

(2)箭头函数

匿名函数的语法还可以进一步的简化,只保留参数列表和函数体两个核心部分,两者用=>符号连接。()=>{}

let numbers: number[] = [1, 2, 3, 4, 5]
numbers.forEach((num) => { console.log(num) })

五、类

1、概述

  • 类(class)是面向对象编程语言中的一个重要概念。
    面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,其核心理念在于将程序中的数据与操作数据的方法有机地组织成对象,从而使程序结构更加模块化和易于理解。通过对象之间的协同合作,实现更为复杂的程序功能。
  • 类(class)是对象的蓝图或模板,它定义了对象的属性(数据)和行为(方法)。通过类可以创建多个具有相似结构和行为的对象。例如定义一个 Person类,其对象可以有张三、李四等等。

2、语法说明

(1)类的定义

在这里插入图片描述

class Person {
    id: number;
    name: string;
    age: number = 18;

    constructor(id: number, name: string) {
        this.id = id;
        this.name = name;
    }

    introduce(): string {
        return `hello,I am ${this.name},and I am ${this.age} years old`
    }
}

(2)对象创建

  • 创建对象的关键字为new,具体语法如下
let person = new Person(1,'zhangsan');
  • 对象属性的访问
console.log(person.name); //读

person.name = 'lisi'; //写

console.log(person.name);
  • 对象创建后,便可通过对象调用类中声明的方法,如下
let intro = person.introduce();
console.log(intro);

(3)静态成员(静态属性和静态方法)

  • 静态成员隶属于类本身,而不属于某个对象实例。静态成员通用用于定义一些常量,或者工具方法。
  • 定义静态成员需要使用static关键字。
class Constants{
    static count:number=1;
}

class Utils{
    static toLowerCase(str:string){
        return str.toLowerCase();
    }
}

  • 静态成员无需通过对象实例访问,直接通过类本身访问即可。
console.log(Constants.count);
console.log(Utils.toLowerCase('Hello World'));

3、继承

继承是面向对象编程中的重要机制,允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。子类可以直接使用父类的特性,并根据需要添加新的特性或覆盖现有的特性。这种机制赋予面向对象程序良好的扩展性。

  • 类的继承需要使用关键字extends
  • 子类构造器中需使用 super() 调用父类构造器对继承自父类的属性进行初始化。
  • 在子类中可以使用this关键字访问继承自父类的属性和方法。
  • 在子类中可以使用super关键字访问父类定义的方法
class Student extends Person {
    classNumber: string;
    constructor(id: number, name: string, classNumber: string) {
        super(id, name);
        this.classNumber = classNumber;
    }

    introduce(): string {
        return super.introduce()+`, and I am a student`;
    }
}

let student = new Student(1,'xiaoming','三年二班');
console.log(student.introduce());

4、访问修饰符

访问修饰符(Access Modifiers)用于控制类成员(属性、方法等)的可访问性。TypeScript提供了三种访问修饰符,分别是 privateprotectedpublic

  • private 修饰的属性或方法是私有的,只能在声明它的类中的被访问。
  • protected 修饰的属性或方法是受保护的,只能在声明它的类和其子类中被访问。
  • public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的。
class Person {
    private id: number;
    protected name: string;
    public age: number;

    constructor(id: number, name: string, age: number) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

class Student extends Person {
     getName() {
        return this.name;
    }
}

let zs = new Student(1, 'zs', 12)
console.log(zs.age, zs.getName())

六、接口

1、概述

接口interface)是面向对象编程中的另一个重要概念。接口通常会作为一种契约或规范让class)去遵守,确保类实现某些特定的行为或功能。

2、语法说明

  • 接口使用interface关键字定义,通常情况下,接口中只会包含属性和方法的声明,而不包含具体的实现细节,具体的细节由其实现类完成。
interface Person {
    id: number;
    name: string;
    age: number;
  
    introduce(): void;
}
  • 接口实现需要用到implements关键字,实现类中,需要包含接口属性的赋值逻辑,以及接口方法的实现逻辑
class Student implements Person {
    id: number;
    name: string;
    age: number;

    constructor(id: number, name: string, age: number) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    introduce(): void {
        console.log('Hello,I am a student');
    }
}

3、多态

多态是面相对象编程中的一个重要概念,它可以使同一类型的对象具有不同的行为。下面我们通过一个具体的案例来体会多态这一概念。

  • 首先,再创建一个Person接口的实现类Teacher,如下
class Teacher implements Person {
    id: number;
    name: string;
    age: number;

    constructor(id: number, name: string, age: number) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    introduce(): void {
        console.log('Hello,I am a teacher');
    }
}
  • 然后分别创建一个Student对象和一个Teacher对象,注意两个对象的类型均可以设置Person,如下
let p1: Person = new Student(1, 'zhangsan', 17);
let p2: Person = new Teacher(2, 'lisi', 35);
  • 最后分别调用p1和p2的introduce()方法,你会发现,同样是Person类型的两个对象,调用同一个introduce()方法时,表现出了不同的行为,这就是多态
p1.introduce();//Hello,I am a student
p2.introduce();//Hello,I am a teacher

4、接口的作用

在传统的面向对象编程的场景中,接口主要用于设计和组织代码,使代码更加容易扩展和维护。下面举例说明。

假如现在需要实现一个订单支付系统,按照面向对象编程的习惯,首先需要定义一个订单类(Order),如下

class Order {
    totalAmount: number;

    constructor(totalAmount: number) {
        this.totalAmount = totalAmount;
    }

    pay() {
        console.log(`AliPay:${this.totalAmount}`);
    }
}

很容易预想到,这个系统将来可能需要支持其他的支付方式,为了方便代码支持新的支付方式,我们可以对代码进行如下改造。

首先定义一个支付策略的接口,接口中声明一个pay方法,用来规范实现类必须实现支付逻辑。

interface PaymentStrategy {
    pay(amount: number): void;
}

然后在订单类中增加一个PaymentStrategy属性,并且在订单类中的pay方法中调用PaymentStrategypay方法,如下

class Order {
    totalAmount: number;
    paymentStrategy: PaymentStrategy;

    constructor(totalAmount: number, paymentStrategy: PaymentStrategy) {
        this.totalAmount = totalAmount;
        this.paymentStrategy = paymentStrategy;
    }

    pay() {
        this.paymentStrategy.pay(this.totalAmount);
    }
}

这样改造完之后,就可以很容易的在不改变现有代码的情况下,支持新的支付方式了。

比如现在需要支持AliPay,那我们就可以创建AliPay这个类class)并实现implementPaymentStrategy这个接口,如下

class AliPay implements PaymentStrategy {
    pay(amount: number): void {
        console.log(`AliPay:${amount}`);
    }
}

这样一来,之后创建的订单就可以使用AliPay这个支付方式了。

let order = new Order(1000,new AliPay());
order.pay();

5、TS 中的接口的特殊性

TypeScript 中的接口是一个非常灵活的概念,除了用作类的规范之外,也常用于直接描述对象的类型,例如,现有一个变量的定义如下

let person: {name:string, age:number, gender:string} = {name:'张三', age:10, gender:'男'};

可以看到变量的值为一个一般对象,变量的类型为{name:string, age:number, gender:string},此时就可以声明一个接口来描述该对象的类型,如下

interface Person {
    name: string;
    age: number;
    gender: string;
}

let person: Person = {name:'张三', age:10, gender:'男'};

七、枚举

1、概述

枚举(Enumeration)是编程语言中常见的一种数据类型,其主要功能是定义一组有限的选项,例如,方向(上、下、左、右)或季节(春、夏、秋、冬)等概念都可以使用枚举类型定义。

2、语法说明

  • 枚举定义需使用enum关键字,如下
enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER
}

枚举使用

  • 枚举值的访问:像访问对象属性一样访问枚举值,例如Season.SPRING
  • 枚举值的类型:枚举值的类型为enum的名称,例如Season.SPRINGSeason.SUMMER等值的类型都是Season
let spring:Season = Season.SPRING;

使用场景

现需要编写一个函数move,其功能是根据输入的方向(上、下、左、右)进行移动,此时就可以先使用枚举定义好所有可能的输入选项,如下

enum Direction {
    UP,
    BOTTOM,
    LEFT,
    RIGHT
}

move函数的实现如下

function move(direction: Direction) {
    if(direction===Direction.UP){
        console.log('向上移动');
    }else if(direction===Direction.BOTTOM){
        console.log('向下移动');
    }else if(direction===Direction.LEFT){
        console.log('向左移动');
    }else{
        console.log('向右移动');
    }
}

move(Direction.UP);

3、赋值

  • 在TypeScript 中,枚举实际上是一个对象,而每个枚举值都是该对象的一个属性,并且每个属性都有具体的值,属性值只支持两种类型——数字或字符串。
  • 默认情况下,每个属性的值都是数字,并且从 0 开始递增,例如上述案例中的Direction枚举中,Direction.UP的值为0,Direction.BOTTOM的值为1,依次类推,具体如下
console.log(Direction.UP) //0
console.log(Direction.BOTTOM) //1
console.log(Direction.LEFT) //2
console.log(Direction.RIGHT) //3
  • 除了使用默认的数字作为属性的值,我们还能手动为每个属性赋值,例如
enum Direction {
    UP = 1,
    BOTTOM = 2,
    LEFT = 3,
    RIGHT = 4
}

console.log(Direction.UP) //1
console.log(Direction.BOTTOM) //2
console.log(Direction.LEFT) //3
console.log(Direction.RIGHT) //4
  • 再例如
enum Direction {
    UP = 'up',
    BOTTOM = 'bottom',
    LEFT = 'left',
    RIGHT = 'right'
}

console.log(Direction.UP) //up
console.log(Direction.BOTTOM) //bottom
console.log(Direction.LEFT) //left
console.log(Direction.RIGHT) //right
  • 通过为枚举属性赋值,可以赋予枚举属性一些更有意义的信息,例如以下枚举
enum Color {
    Red = 0xFF0000,
    Green = 0x00FF00,
    Blue = 0x0000FF
}

enum FontSize {
    Small = 12,
    Medium = 16,
    Large = 20,
    ExtraLarge = 24
}

八、模块化

1、概述

模块化是指将复杂的程序拆解为多个独立的文件单元,每个文件被称为一个模块。在 TypeScript 中,默认情况下,每个模块都拥有自己的作用域,这意味着在一个模块中声明的任何内容(如变量、函数、类等)在该模块外部是不可见的。为了在一个模块中使用其他模块的内容,必须对这些内容进行导入、导出。

在这里插入图片描述

2、语法说明

  • 导出须使用export关键字,语法如下
//moduleA.ts
export function hello() {
    console.log('hello module A');
}

export const str = 'hello world';

const num = 1;
  • 导入须使用import关键字,语法如下
// moduleB.ts
import { hello, str } from './moduleA';

hello();
console.log(str);

3、避免命名冲突

若多个模块中具有命名相同的变量、函数等内容,将这些内容导入到同一模块下就会出现命名冲突。例如,在上述案例的基础上,又增加了一个 moduleC,内容如下

// moduleC.ts
export function hello() {
    console.log('hello module C');
}

export const str = 'module C';

moduleB 同时引入 moduleAmoduleC 的内容,如下,显然就会出命名冲突

// moduleB.ts
import { hello, str } from "./moduleA";
import { hello, str } from "./moduleC";

hello() //?
console.log(str); //?

有多种方式可以用来解决命名冲突,下面逐一介绍

  • 导入重命名
import { hello as helloFromA, str as strFromA } from "./moduleA";
import { hello as helloFromC, str as strFromC } from "./moduleC";

helloFromA();
console.log(strFromA);

helloFromC();
console.log(strFromC);
  • 创建模块对象

上述导入重命名的方式能够很好的解决命名冲突的问题,但是当冲突内容较多时,这种写法会比较冗长。除了导入重命名外,还可以将某个模块的内容统一导入到一个模块对象上,这样就能简洁有效的解决命名冲突的问题了,具体语法如下

import * as A from "./moduleA";
import * as C from "./moduleC";

A.hello();
console.log(A.str);

C.hello();
console.log(C.str);

4、默认导入导出

默认导出允许一个模块指定一个(最多一个)默认的导出项,语法如下

export default function hello(){
    console.log('moduleA');
}

默认导入无需关注导入项的原始名称,并且无需使用{}

import helloFromA from "./moduleA";

由于默认导入时无需关注导入项的名称,所以默认导出支持匿名内容,比如匿名函数,语法如下

export default function () {
    console.log('moduleB');
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/399632.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++学习Day08之类模板碰到继承的问题以及解决

目录 一、程序及输出1.1 指定父类T数据类型1.2 子类T指定父类T数据类型 二、分析与总结 一、程序及输出 1.1 指定父类T数据类型 必须要指定出父类中的T数据类型&#xff0c;才能给子类分配内存 正确使用 &#xff1a; #include<iostream> using namespace std;templa…

webpack打包速度优化思维导图

webpack打包速度优化思维导图 前言附件 前言 去年的时候公司一个项目体积过大&#xff0c;我是m1芯片的macpro&#xff0c;光启动就要1分钟&#xff0c;配置差点都电脑&#xff0c;启动就要3分钟&#xff0c;自然打包速度也会慢很多&#xff0c;我们是gitlab设置成了自动打包的…

春招面试准备笔记——NMS(非极大值抑制)算法

NMS&#xff08;非极大值抑制&#xff09;算法非极大值抑制是用于减少物体检测算法中重叠边界框或区域的数量的技术。通过对每个类别的检测框按置信度排序&#xff0c;然后逐个遍历&#xff0c;保留置信度最高的框&#xff0c;并抑制与其重叠且置信度低的框&#xff0c;从而得到…

Apache Httpd 常见漏洞解析(全)

一、Apache HTTPD 换行解析漏洞 漏洞编号&#xff1a;CVE-2017-15715 Apache HTTPD是一款HTTP服务器&#xff0c;它可以通过mod_php来运行PHP网页。 其2.4.0~2.4.29版本中存在一个解析漏洞。 在解析PHP时&#xff0c;1.php\x0A将被按照PHP后缀进行解析&#xff0c;导致绕过…

桌面备忘录怎么设置,怎么在电脑上设置提醒?

桌面备忘录怎么设置&#xff0c;怎么在电脑上设置提醒&#xff1f;如今&#xff0c;为了优质生活的需要&#xff0c;我们每天都会处理很多的事情&#xff0c;比如&#xff1a;网课时间、工作任务、生活琐事……有时候&#xff0c;真恨不得自己有个三头六臂&#xff0c;好把这一…

前端|JavaScript 基础 - 第2天(黑马笔记)

JavaScript 基础 - 第2天 目录 JavaScript 基础 - 第2天一、运算符1.算术运算符2.赋值运算符3.自增/自减运算符4.比较运算符5.逻辑运算符6.运算符优先级 二、语句1.表达式和语句2.分支语句if 分支语句if双分支语句if 多分支语句三元运算符&#xff08;三元表达式&#xff09;sw…

分治算法总结(Java)

目录 分治算法概述 快速排序 练习1&#xff1a;排序数组 练习2&#xff1a;数组中的第K个最大元素 练习3&#xff1a;最小k个数 归并排序 练习4&#xff1a;排序数组 练习5&#xff1a;交易逆序对的总数 练习6&#xff1a;计算右侧小于当前元素的个数 练习7&#xff1…

视频推拉流EasyDSS视频直播点播平台授权出现激活码无效并报错400是什么原因?

视频推拉流EasyDSS视频直播点播平台集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务&#xff0c;在应用场景上&#xff0c;平台可以运用在互联网教育、在线课堂、游戏…

Project_Euler-06 题解

Project_Euler-06 题解 题目描述 两个公式 等差数列求和公式 i i i项&#xff1a; a i a_{i} ai​ 项数&#xff1a; n n n 公差&#xff1a; d d d 和&#xff1a; S n S_{n} Sn​ a n a 1 ( n − 1 ) d S n n ( a 1 a n ) 2 a_{n} a_{1} (n - 1)d\\ S_{n} \frac{n(a_…

在哪些领域中最需要使用 OCR 识别技术?真实场景介绍

根据我们的项目经验总结来说&#xff0c;OCR&#xff08;光学字符识别&#xff09;技术在多个领域中扮演着至关重要的角色&#xff0c;它能够将图像中的文本内容转换为机器可读的格式&#xff0c;极大地提高了数据处理的效率和准确性。以下是一些主要领域及其对应的应用场景和用…

ubuntu22.04@laptop OpenCV Get Started: 012_mouse_and_trackbar

ubuntu22.04laptop OpenCV Get Started: 012_mouse_and_trackbar 1. 源由2. mouse/trackbar应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 鼠标位置跟踪注释3.1 注册回调函数3.2 回调操作3.3 效果 4. 使用轨迹栏调整图像大小4.1 初始化轨迹栏&注册回调函数4.2 回调操作4.3 效…

每期十万,等你来战|AI原生应用开发挑战赛首期精彩回顾

随着大模型技术的飞速发展&#xff0c;2024年将会成为AI原生应用爆发的元年&#xff0c;引领千行百业的创新变革。在这一时代背景下&#xff0c;百度智能云重磅推出千帆杯AI原生应用开发挑战赛&#xff0c;旨在激发广大开发者的创意潜能&#xff0c;推动AI原生应用在中国市场的…

16:00面试,16:09就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到算法死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内…

STM32 TIM2重映射

STM32定时器 文章目录 STM32定时器[TOC](文章目录) 前言一、问题分析二、代码 前言 最近想弄一个多路输出PWM&#xff0c;但是发现TIM2不能用&#xff0c;根据手册也对它进行重映射了&#xff0c;但是还是不能用&#xff0c;用示波器发现驱动能力比较弱&#xff0c;然后禁用jt…

羊大师讲解,羊奶奶源是如何影响羊奶品质的呢?

羊大师讲解&#xff0c;羊奶奶源是如何影响羊奶品质的呢&#xff1f; 1.营养成分和口感&#xff1a;由于奶源地的不同&#xff0c;土壤、气候和牧草种类等自然条件的差异会导致羊奶的营养成分和口感有所差异。高品质的奶源地能够提供丰富的营养和优质的牧草&#xff0c;因此羊…

wo-gradient-card是一款采用uniapp实现的透明辉光动画卡片

采用uniapp-vue3实现&#xff0c;透明辉光动画卡片&#xff0c;卡片内容包含标签、标题、副标题、图片 支持H5、微信小程序&#xff08;其他小程序未测试过&#xff0c;可自行尝试&#xff09; 可用于参考学习 可到插件市场下载尝试&#xff1a; https://ext.dcloud.net.cn/plu…

刷LeetCode541引起的java数组和字符串的转换问题

起因是今天在刷下面这个力扣题时的一个报错 541. 反转字符串 II - 力扣&#xff08;LeetCode&#xff09; 这个题目本身是比较简单的&#xff0c;所以就不讲具体思路了。问题出在最后方法的返回值处&#xff0c;要将字符数组转化为字符串&#xff0c;第一次写的时候也没思考直…

VIO第3讲:基于优化的IMU与视觉信息融合之IMU预积分

VIO第3讲&#xff1a;基于优化的IMU与视觉信息融合之IMU预积分 文章目录 VIO第3讲&#xff1a;基于优化的IMU与视觉信息融合之IMU预积分1 IMU预积分1.1 IMU常规积分—连续时间—不适用1.2 预积分形式① 定义② 如何推导出预积分定义③ 用预积分表达IMU积分公式④ 预积分误差&am…

APP要做哪些测试?APP测试要注意哪些问题?

APP要做哪些测试&#xff1f;APP测试要注意哪些问题&#xff1f;对于移动测试&#xff0c;测试员不得不基于用户移动使用模式考虑移动相关的功能。而针对手机应用软件APP的系统测试&#xff0c;我们通常从如下几个角度开展&#xff1a;功能测试(流程测试、功能点测试)、兼容性测…

WEB APIs (3)

事件对象 事件对象有事件触发时的相关信息&#xff0c;如点击事件中事件对象储存了鼠标点在哪个位置的信息 场景&#xff1a; 用户按下了哪个键&#xff0c;按下回车键可以发布新闻 鼠标点击了哪个元素&#xff0c;从而做哪些操作 参数e为事件对象 常用属性 type 获取当前…