TypeScript学习笔记

文章目录

    • [1. 简介](#1. 简介)
    • [2. TypeScript环境搭建](#2. TypeScript环境搭建)
    • [3. TS类型](#3. TS类型)
    • [4. TS编译选项](#4. TS编译选项)
    • [5. webpack](#5. webpack)
    • [6. Babel](#6. Babel)
    • [7. 类(Class)](#7. 类(Class))
    • [8. 面向对象的特点](#8. 面向对象的特点)
    • [9. 接口(Interface)](#9. 接口(Interface))
    • [10. 泛型(Generic)](#10. 泛型(Generic))

1. 简介

TS以JavaScript为基础构建的语言,一个JavaScript的超集,可以在任何支持JS的平台中执行,TS扩展了JS,并添加了类型,TS不能被JS解析器直接执行,要将TS编译程JS才能够执行。

TS增加了:在·

  • 类型
  • 支持ES的新特性
  • 添加ES不具备的新特性
  • 丰富的配置选项
  • 强大的开发工具

2. TypeScript环境搭建

1. 下载Node.js

https://nodejs.org/zh-cn/

2. 安装Node.js

3. 使用npm全局安装TypeScript

  • cmd进入命令行
  • 输入:npm i -g typescript

4. 创建一个TS文件

5. 使用tsc对ts文件进行编译

  • 进入cmd

  • 进入ts文件所在目录

  • 执行命令:tsc xxx.ts,便会生成一个对应的js文件


3. TS类型

1. 类型声明

  • 类型声明是TS非常重要的一个特点

  • 通过类型声明可以指定TS中变量(参数、形参)的类型

  • 指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错

  • 简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值

  • 语法

    typescript 复制代码
    let 变量: 类型;
    let 变量: 类型 = 值;
    function fn(参数: 类型,参数: 类型):类型{
        ...
    }
        
    // 声明一个变量a,并且声明变量a的类型为number
    // 在以后的使用过程中,a的值只能为数字
    let a : number;
    a = 10;
    a = 'hello';  // 会报错
        
    let b : boolen = false; // 在直接赋值时 不需要指定类型,TS可以自动识别
    let c = false;
    c = 123; // 会报错
        
    // 函数中的类型
    function sum(a:number,b:number) : number{
        return a + b;
    }

2. 自动类型判断

  • TS拥有自动的类型判断机制
  • 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
  • 所以如果你的变量的声明和赋值是同时进行的,可以省略掉类型声明

3. 类型

类型 列子 秒速
number 1,-33,2.5 任意数字
string 'hi',"hi",hi 任意字符串
boolean true,false 布尔值true或者false
字面量 其本身 限制变量的值就是该字面量的值
any * 任意类型(相当于关闭了类型检测,和JS无区别)
unknown * 类型安全的any
void 控制(undefined) 没有值(或undefined)
never 没有值 不能是任何值
object {name:'孙悟空'} 任意的js对象
array [1,2,3] 任意js数组
tuple [4,5] 元素,TS新增类型,固定长度数组
enum enum(A,B) 枚举,TS中新增类型

声明变量时,不指定类型且不进行赋值,变量类型自动为any。(隐式any)

any变量可以赋值给任何变量,如

typescript 复制代码
let p:number;
let q:any;

p = q;

unknown类型变量不可以直接赋值给其他变量。若需要将unknown类型的变量赋值给其他变量,需要先进行类型检查,如:

typescript 复制代码
let t:string;
let e:unknown;
e = "hello";
if (typeof e === "string"){
    t = e;   
}

类型断言:告诉解析器变量的实际类型

typescript 复制代码
语法: 1. 变量 as 类型
      2. <类型> 变量

// 类型断言 告诉解析器 变量e 为字符串类型
t = e as string
或者
t = <string>e

object类型

typescript 复制代码
let person : {name:string};  // 规定person为一个对象类型,且必须含有字符串类型的name属性
person = {};  // 会报错
person = {name:'张三',age:12}  //会报错
person = {name:'孙悟空'}

// 当在属性后加一个问号`?` 表示该属性可选,可有可无
let dog : {height:string,weight:string,name?:string};

dog = {height:"12",weight:"12"}
dog = {height:"12",weight:"12",name:"小白"}

[propName:string]:any表示可以有任意属性

typescript 复制代码
let tt : {name:string,[propName:string]:any}  // 要求必须一个string类型的name,其他属性任意

tt = {name:"haha",age:12,gender:"男"}

函数中的类型:

typescript 复制代码
// d是一个函数, 需要两个number类型的变量,返回值为number类型
let d: (a:number,b:number) => number;

数组类型:

typescript 复制代码
let f: number[]; // 表示数值数组
let g: Array<any>;
let h: Array<string>;

元组类型:元组就是固定长度的数组。

typescript 复制代码
let j : [string,number,string];
j = ["hello",123,"yes",123] // 会报错
j = ["hello",123,23]  // 会报错
j = ["hello",123,"yes"] // 正确

枚举类型:

typescript 复制代码
enum Gender{
    Male = 0,
    Femal = 1
}

let i :{name:string,gender:number}
i = {
    name:'张三',
    gender:Gender.Male
}

|&且:

typescript 复制代码
let k : string | number; // 表示变量j的类型为string或number
k = "haha"
k = 1234

let l: string & number; // 表示变量j的类型为string和number
let l: {name:string} & {age:number}
l = {name:"haha",age:12}

类型别名:

typescript 复制代码
type mytype = string;  // 给string类型取了一个别名叫做mytype
let m: mytype;
m = "hahah";

type mytype2 = 1|2|3|4;  // 值只能从1 2 3 4 中取
let n: mytype2;
n = 1;
n = 5; //错误

4. TS编译选项

  • 自动编译文件

    编译文件时,使用-w指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件进行重新编译。

    示例:

    shell 复制代码
    tsc xxx.ts -w
  • 自动编译整个项目

    如果直接使用tsc指令,则可以自动将当前项目下所有的ts文件编译为js文件

    但是,能直接使用tsc指令的前提是,要先在项目根目录下创建一个ts的配置文件tsconfig.json

    tsconfig.json是一个JSON文件,添加配置文件后,只需tsc命令即可完成对整个项目的编译

    配置选项:

    • include

      • 定义希望被编译文件所在的目录

      • 默认值:["**/*"],**表示任意目录,*表示任意文件

      • 示例:

        json 复制代码
        "include":["scr/**/*","tests/**/*"]

        上述示例中,所有src目录和tests目录下的文件都会被编译

    • exclude

      • 定义需要排除在外的目录

      • 默认值:["node_modules","bower_components","jspm_packages"]

      • 示例:

        json 复制代码
        "exclude":["./src/hello/**/*"]
    • files

      • 指定被编译文件的列表,只有需要编译的文件少时才会用到

      • 示例:

        json 复制代码
        "files": [
            "core.ts",
            "sys.ts",
            "types.ts",
            "scanner.ts",
            "parser.ts",
            "utilities.ts",
            "binder.ts",
            "checker.ts",
            "tsc.ts"
          ]
      • 列表中的文件都会被TS编译器所编译

    • compilerOptions

      • 编译选项是配置文件中非常重要也比较复杂的配置选项

      • 在compilerOptions中包含多个子选项,用来完成对编译的配置

      • 项目选项:

        • target

          • 设置ts代码编译的目标版本

          • 可选值:

            • ES3(默认)、ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext
          • 示例:

            json 复制代码
            "compilerOptions": {
                "target": "ES6"
            }
            • 如上设置,我们所编写的ts代码将会被编译为ES6版本的js代码
        • lib

          • 指定代码运行时所包含的库(宿主环境)

          • 可选值:

            • ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext、DOM、WebWorker、ScriptHost ...
          • 示例:

            json 复制代码
            "compilerOptions": {
                "target": "ES6",
                "lib": ["ES6", "DOM"],
                "outDir": "dist",
                "outFile": "dist/aa.js"
            }
        • module

          • 设置编译后代码使用的模块化系统

            • 可选值:

              • CommonJS、UMD、AMD、System、ES2020、ESNext、None
            • 示例:

              typescript 复制代码
              "compilerOptions": {
                  "module": "CommonJS"
              }
        • outDir

          • 编译后文件的所在目录

            • 默认情况下,编译后的js文件会和ts文件位于相同的目录,设置outDir后可以改变编译后文件的位置

            • 示例:

              json 复制代码
              "compilerOptions": {
                  "outDir": "dist"
              }
              • 设置后编译后的js文件将会生成到dist目录
        • outFile

          • 将所有的文件编译为一个js文件

          • 默认会将所有的编写在全局作用域中的代码合并为一个js文件,如果module制定了None、System或AMD则会将模块一起合并到文件之中

          • 示例:

            json 复制代码
            "compilerOptions": {
                "outFile": "dist/app.js"
            }
        • rootDir

          • 指定代码的根目录,默认情况下编译后文件的目录结构会以最长的公共目录为根目录,通过rootDir可以手动指定根目录

          • 示例:

            json 复制代码
            "compilerOptions": {
                "rootDir": "./src"
            }
        • allowJs

          • 是否对js文件编译
        • checkJs

          • 是否对js文件进行检查

          • 示例:

            json 复制代码
            "compilerOptions": {
                "allowJs": true,
                "checkJs": true
            }
        • removeComments

          • 是否删除注释
          • 默认值:false
        • noEmit

          • 不对代码进行编译
          • 默认值:false
        • sourceMap

          • 是否生成sourceMap
          • 默认值:false
      • 严格检查

        • strict
          • 启用所有的严格检查,默认值为true,设置后相当于开启了所有的严格检查
        • alwaysStrict
          • 总是以严格模式对代码进行编译
        • noImplicitAny
          • 禁止隐式的any类型
        • noImplicitThis
          • 禁止类型不明确的this
        • strictBindCallApply
          • 严格检查bind、call和apply的参数列表
        • strictFunctionTypes
          • 严格检查函数的类型
        • strictNullChecks
          • 严格的空值检查
        • strictPropertyInitialization
          • 严格检查属性是否初始化
      • 额外检查

        • noFallthroughCasesInSwitch
          • 检查switch语句包含正确的break
        • noImplicitReturns
          • 检查函数没有隐式的返回值
        • noUnusedLocals
          • 检查未使用的局部变量
        • noUnusedParameters
          • 检查未使用的参数
      • 高级

        • allowUnreachableCode
          • 检查不可达代码
          • 可选值:
            • true,忽略不可达代码
            • false,不可达代码将引起错误
        • noEmitOnError
          • 有错误的情况下不进行编译
          • 默认值:false

5. webpack

  • 通常情况下,实际开发中我们都需要使用构建工具对代码进行打包,TS同样也可以结合构建工具一起使用,下边以webpack为例介绍一下如何结合构建工具使用TS。

  • 步骤:

    1. 初始化项目

      • 进入项目根目录,执行命令 npm init -y

        • 主要作用:创建package.json文件
  1. 下载构建工具

    • npm i -D webpack webpack-cli webpack-dev-server typescript ts-loader clean-webpack-plugin
      • 共安装了7个包
        • webpack
          • 构建工具webpack
        • webpack-cli
          • webpack的命令行工具
        • webpack-dev-server
          • webpack的开发服务器
        • typescript
          • ts编译器
        • ts-loader
          • ts加载器,用于在webpack中编译ts文件
        • html-webpack-plugin
          • webpack中html插件,用来自动创建html文件
        • clean-webpack-plugin
          • webpack中的清除插件,每次构建都会先清除目录
  2. 根目录下创建webpack的配置文件webpack.config.js

    javascript 复制代码
    // 引入一个包
    const path = require("path");
    
    // 引入html插件
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    
    // 引入clean插件
    const { CleanWebpackPlugin } = require('clean-webpack-plugin')
    
    // webpack 中所有的配置信息都应写在module.exports中
    module.exports = {
        // 入口文件
        entry: './src/index.ts',
        // 指定打包文件所输出的目录
        output: {
            // 指定打包后的目录
            path: path.resolve(__dirname,'dist'),
            // 打包后文件的名字
            filename: "bundle.js",
            // 配置打包的环境,告诉webpack不使用箭头函数
            environment: {
                arrowFunction: false
            }
        },
        // 指定webpack打包时要使用的模块
        module: {
            // 指定加载的规则
            rules: [
                {
                    // test指定规则生效的文件,写正则表达式
                    test: /\.ts$/,
                    // 要使用的loader
                    use: [
                        // 配置Babel
                        {
                            // 指定加载器
                            loader: "babel-loader",
                            // 设置babel
                            options: {
                                // 设置预定义的环境
                                presets : [
                                    [
                                        // 指定环境的插件
                                        "@babel/preset-env",
                                        // 配置信息
                                        {
                                            // 要兼容的目标浏览器
                                            targets: {
                                                "chrome":"88",
                                                "ie":"11"
                                            },
                                            // 指定corejs的版本
                                          "corejs":"3",
                                            // 使用corejs的方式  usage:表示按需加载
                                          "useBuiltIns":"usage"
                                        }
                                    ]
                                ]
                            }
                        },
                        'ts-loader'
                    ],
                    // 要排除的文件夹
                    exclude: /node-modules/
              }
            ]
      },
        mode: 'production',
        // 配置webpack插件
        plugins: [
            new HtmlWebpackPlugin({
                // title: "这是一个自定义的Title"
                // 指定模板
                template: "./src/index.html"
            }),
            new CleanWebpackPlugin()
        ],
        // 用来设置引用模块
      resolve: {
            extensions: ['.ts','.js']
        }
    }
  3. 根目录下创建tsconfig.json,配置可以根据自己需要

    json 复制代码
    {
      "compilerOptions": {
        "module": "ES6",
        "target": "ES6",
        "strict": true
      }
    }
  4. 修改package.json添加如下配置

    json 复制代码
    {
      ...略...
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack",
        "start": "webpack serve --open"
      },
      ...略...
    }
  5. 在src下创建ts文件,并在并命令行执行npm run build对代码进行编译,或者执行npm start来启动开发服务器


6. Babel

  • 经过一系列的配置,使得TS和webpack已经结合到了一起,除了webpack,开发中还经常需要结合babel来对代码进行转换以使其可以兼容到更多的浏览器,在上述步骤的基础上,通过以下步骤再将babel引入到项目中。

    1. 安装依赖包:

      • npm i -D @babel/core @babel/preset-env babel-loader core-js
      • 共安装了4个包,分别是:
        • @babel/core
          • babel的核心工具
        • @babel/preset-env
          • babel的预定义环境
        • @babel-loader
          • babel在webpack中的加载器
        • core-js
          • core-js用来使老版本的浏览器支持新版ES语法
    2. 修改webpack.config.js配置文件

      javascript 复制代码
      ...略...
      module: {
          rules: [
              {
                  test: /\.ts$/,
                  use: [
                      {
                          loader: "babel-loader",
                          options:{
                              presets: [
                                  [
                                      "@babel/preset-env",
                                      {
                                          "targets":{
                                              "chrome": "58",
                                              "ie": "11"
                                          },
                                          "corejs":"3",
                                          "useBuiltIns": "usage"
                                      }
                                  ]
                              ]
                          }
                      },
                      {
                          loader: "ts-loader",
      
                      }
                  ],
                  exclude: /node_modules/
              }
          ]
      }
      ...略...
      • 如此一来,使用ts编译后的文件将会再次被babel处理,使得代码可以在大部分浏览器中直接使用,可以在配置选项的targets中指定要兼容的浏览器版本。

7. 类(Class)

要想面向对象,操作对象,首先便要拥有对象,那么下一个问题就是如何创建对象。要创建对象,必须要先定义类,所谓的类可以理解为对象的模型,程序中可以根据类创建指定类型的对象,举例来说:可以通过Person类来创建人的对象,通过Dog类创建狗的对象,通过Car类来创建汽车的对象,不同的类可以用来创建不同的对象。

定义类:

typescript 复制代码
class 类名 {
	属性名: 类型;
	
	constructor(参数: 类型){
		this.属性名 = 参数;
	}
	
	方法名(){
		....
	}

}

示例:

typescript 复制代码
class Person{
    name: string;
    age: number;

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

    sayHello(){
        console.log(`大家好,我是${this.name}`);
    }
}

使用类:

typescript 复制代码
const p = new Person('孙悟空', 18);
p.sayHello();

8. 面向对象的特点

封装

  • 对象实质上就是属性和方法的容器,它的主要作用就是存储属性和方法,这就是所谓的封装

  • 默认情况下,对象的属性是可以任意的修改的,为了确保数据的安全性,在TS中可以对属性的权限进行设置

  • 只读属性(readonly):

    • 如果在声明属性时添加一个readonly,则属性便成了只读属性无法修改
  • TS中属性具有三种修饰符:

    • public(默认值),可以在类、子类和对象中修改
    • protected ,可以在类、子类中修改
    • private ,可以在类中修改
  • 示例:

    • public

      type 复制代码
      class Person{
          public name: string; // 写或什么都不写都是public
          public age: number;
      
          constructor(name: string, age: number){
              this.name = name; // 可以在类中修改
              this.age = age;
          }
      
          sayHello(){
              console.log(`大家好,我是${this.name}`);
          }
      }
      
      class Employee extends Person{
          constructor(name: string, age: number){
              super(name, age);
              this.name = name; //子类中可以修改
          }
      }
      
      const p = new Person('孙悟空', 18);
      p.name = '猪八戒';// 可以通过对象修改
    • protected

      typescript 复制代码
      class Person{
          protected name: string;
          protected age: number;
      
          constructor(name: string, age: number){
              this.name = name; // 可以修改
              this.age = age;
          }
      
          sayHello(){
              console.log(`大家好,我是${this.name}`);
          }
      }
      
      class Employee extends Person{
      
          constructor(name: string, age: number){
              super(name, age);
              this.name = name; //子类中可以修改
          }
      }
      
      const p = new Person('孙悟空', 18);
      p.name = '猪八戒';// 不能修改
    • private

      typescript 复制代码
      class Person{
          private name: string;
          private age: number;
      
          constructor(name: string, age: number){
              this.name = name; // 可以修改
              this.age = age;
          }
      
          sayHello(){
              console.log(`大家好,我是${this.name}`);
          }
      }
      
      class Employee extends Person{
      
          constructor(name: string, age: number){
              super(name, age);
              this.name = name; //子类中不能修改
          }
      }
      
      const p = new Person('孙悟空', 18);
      p.name = '猪八戒';// 不能修改
    • 属性存取器

      • 对于一些不希望被任意修改的属性,可以将其设置为private

      • 直接将其设置为private将导致无法再通过对象修改其中的属性

      • 我们可以在类中定义一组读取、设置属性的方法,这种对属性读取或设置的属性被称为属性的存取器

      • 读取属性的方法叫做setter方法,设置属性的方法叫做getter方法

      • 示例:

        typescript 复制代码
        class Person{
            private _name: string;
        
            constructor(name: string){
                this._name = name;
            }
        
            get name(){
                return this._name;
            }
        
            set name(name: string){
                this._name = name;
            }
        
        }
        
        const p1 = new Person('孙悟空');
        console.log(p1.name); // 通过getter读取name属性
        p1.name = '猪八戒'; // 通过setter修改name属性
    • 静态属性

      • 静态属性(方法),也称为类属性。使用静态属性无需创建实例,通过类即可直接使用

      • 静态属性(方法)使用static开头

      • 示例:

        typescript 复制代码
        class Tools{
            static PI = 3.1415926;
            
            static sum(num1: number, num2: number){
                return num1 + num2
            }
        }
        
        console.log(Tools.PI);
        console.log(Tools.sum(123, 456));
    • this

      • 在类中,使用this表示当前对象

继承

  • 继承时面向对象中的又一个特性

  • 通过继承可以将其他类中的属性和方法引入到当前类中

  • 示例:

    typescript 复制代码
    class Animal{
        name: string;
        age: number;
    
        constructor(name: string, age: number){
            this.name = name;
            this.age = age;
        }
    }
    
    class Dog extends Animal{
    
        bark(){
            console.log(`${this.name}在汪汪叫!`);
        }
    }
    
    const dog = new Dog('旺财', 4);
    dog.bark();
  • 通过继承可以在不修改类的情况下完成对类的扩展

  • 重写

    • 发生继承时,如果子类中的方法会替换掉父类中的同名方法,这就称为方法的重写

    • 示例:

      typescript 复制代码
      class Animal{
          name: string;
          age: number;
      
          constructor(name: string, age: number){
              this.name = name;
              this.age = age;
          }
      
          run(){
              console.log(`父类中的run方法!`);
          }
      }
      
      class Dog extends Animal{
      
          bark(){
              console.log(`${this.name}在汪汪叫!`);
          }
      
          run(){
              console.log(`子类中的run方法,会重写父类中的run方法!`);
          }
      }
      
      const dog = new Dog('旺财', 4);
      dog.bark();
    • 在子类中可以使用super来完成对父类的引用

  • 抽象类(abstract class)

    抽象类是专门用来被其他类所继承的类,它只能被其他类所继承不能用来创建实例

    typescript 复制代码
    abstract class Animal{
        abstract run(): void;
        bark(){
            console.log('动物在叫~');
        }
    }
    
    class Dog extends Animals{
        run(){
            console.log('狗在跑~');
        }
    }

    使用abstract开头的方法叫做抽象方法,抽象方法没有方法体只能定义在抽象类中,继承抽象类时抽象方法必须要实现


9. 接口(Interface)

接口的作用类似于抽象类,不同点在于接口中的所有方法和属性都是没有实值的,换句话说接口中的所有方法都是抽象方法。接口主要负责定义一个类的结构,接口可以去限制一个对象的接口,对象只有包含接口中定义的所有属性和方法时才能匹配接口。同时,可以让一个类去实现接口,实现接口时类中要保护接口中的所有属性。

示例(检查对象类型):

typescript 复制代码
interface Person{
    name: string;
    sayHello():void;
}

function fn(per: Person){
    per.sayHello();
}

fn({name:'孙悟空', sayHello() {console.log(`Hello, 我是 ${this.name}`)}});

示例(实现):

typescript 复制代码
interface Person{
    name: string;
    sayHello():void;
}

class Student implements Person{
    constructor(public name: string) {
    }

    sayHello() {
        console.log('大家好,我是'+this.name);
    }
}

10. 泛型(Generic)

定义一个函数或类时,有些情况下无法确定其中要使用的具体类型(返回值、参数、属性的类型不能确定),此时泛型便能够发挥作用。

举个例子:

typescript 复制代码
function test(arg: any): any{
	return arg;
}

上例中,test函数有一个参数类型不确定,但是能确定的时其返回值的类型和参数的类型是相同的,由于类型不确定所以参数和返回值均使用了any,但是很明显这样做是不合适的,首先使用any会关闭TS的类型检查,其次这样设置也不能体现出参数和返回值是相同的类型

使用泛型:

typescript 复制代码
function test<T>(arg: T): T{
	return arg;
}

这里的<T>就是泛型,T是我们给这个类型起的名字(不一定非叫T),设置泛型后即可在函数中使用T来表示该类型。所以泛型其实很好理解,就表示某个类型。

那么如何使用上边的函数呢?

  • 方式一(直接使用):

    typescript 复制代码
    test(10)
    • 使用时可以直接传递参数使用,类型会由TS自动推断出来,但有时编译器无法自动推断时还需要使用下面的方式
  • 方式二(指定类型):

    typescript 复制代码
    test<number>(10)
    • 也可以在函数后手动指定泛型
  • 可以同时指定多个泛型,泛型间使用逗号隔开:

    typescript 复制代码
    function test<T, K>(a: T, b: K): K{
        return b;
    }
    
    test<number, string>(10, "hello");
    • 使用泛型时,完全可以将泛型当成是一个普通的类去使用
  • 类中同样可以使用泛型:

    typescript 复制代码
    class MyClass<T>{
        prop: T;
    
        constructor(prop: T){
            this.prop = prop;
        }
    }
  • 除此之外,也可以对泛型的范围进行约束

    typescript 复制代码
    interface MyInter{
        length: number;
    }
    
    function test<T extends MyInter>(arg: T): number{
        return arg.length;
    }
    • 使用T extends MyInter表示泛型T必须是MyInter的子类,不一定非要使用接口类和抽象类同样适用。
相关推荐
知识分享小能手21 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
汇能感知1 天前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun1 天前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao1 天前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾1 天前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT1 天前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
aaaweiaaaaaa1 天前
HTML和CSS学习
前端·css·学习·html
ST.J1 天前
前端笔记2025
前端·javascript·css·vue.js·笔记
Suckerbin1 天前
LAMPSecurity: CTF5靶场渗透
笔记·安全·web安全·网络安全
叫我阿柒啊1 天前
Java全栈开发工程师的实战面试经历:从基础到微服务
java·微服务·typescript·vue·springboot·前端开发·后端开发