当前位置: 首页 > news >正文

WEB3全栈开发——面试专业技能点P3JavaScript / TypeScript

目录

一、ES6+ 语法

1. let 和 const 变量声明

2. 箭头函数 () => {}

3. 模板字符串

4. 解构赋值

5. 默认参数

6. 展开运算符 ...

7. Promise 和 async/await 异步处理

8. 类(class)和继承

9. 模块导入导出 import 和 export

10. Symbol 类型

11. Map 和 Set 数据结构

12. 生成器函数 function*

13. 可选链操作符 ?.

14. 空值合并运算符 ??

二、Javascript闭包

解释:

三、原型链

1.javascript原型链(经典函数构造器 + prototype)

解释:

2.TypeScript 版本(class 语法)

解释:

3.总结

三、作用域链

作用域链简介

1. JavaScript 版本示例

解释:

2. TypeScript 版本示例

解释:

总结

四、如何使用 TypeScript 构建类型安全的 DApp 项目

1. 使用 TypeScript 定义智能合约接口类型

2. 使用 web3.js 或 ethers.js 连接以太坊并调用合约(示例用 ethers.js)

3. 使用 TypeScript 定义事件类型并监听合约事件

4. 使用类型安全的 ABI 绑定工具(如 TypeChain)

5. 总结

五、泛型

概念

1. 泛型函数示例

解释:

2. 泛型接口示例

解释:

3. 泛型类示例

解释:

4. 泛型约束示例

解释:

六、接口

概念

1. TypeScript 接口示例

解释:

2. JavaScript 中模拟接口(无类型检查)

解释:

应用场景

七、装饰器

📌 一、装饰器是什么?

🧪 二、类装饰器示例

✅ 解释:

📦 三、方法装饰器示例

✅ 解释:

🏷️ 四、属性装饰器示例

✅ 解释:

📌 五、装饰器的应用场景


一、ES6+ 语法

“ES6+ 语法”指的是 ECMAScript 2015(即 ES6)及其之后版本的 JavaScript 语言新特性和语法。简单说,就是现代 JavaScript 的新语法和功能。

常见 ES6+ 语法包括:

  • letconst 变量声明

  • 箭头函数 () => {}

  • 模板字符串 `Hello ${name}`

  • 解构赋值

  • 默认参数

  • 展开运算符 ...

  • Promise 和 async/await 异步处理

  • 类(class)和继承

  • 模块导入导出 importexport

  • Symbol 类型

  • Map 和 Set 数据结构

  • 生成器函数 function*

  • 可选链操作符 ?.

  • 空值合并运算符 ??

1. letconst 变量声明

let a = 10;    // 可变变量
const b = 20;  // 常量,不能重新赋值
// b = 30; // 会报错

解释: let 声明的变量有块级作用域,const 声明常量,值不能变。


2. 箭头函数 () => {}

const add = (x, y) => x + y;
console.log(add(2, 3)); // 5

解释: 箭头函数写法简洁,并且不绑定自己的 this


3. 模板字符串

const name = 'Alice';
console.log(`Hello, ${name}!`);  // Hello, Alice!

解释: 用反引号 ` 包裹,可以直接嵌入变量和表达式。


4. 解构赋值

const person = {name: 'Bob', age: 25};
const {name, age} = person;
console.log(name, age); // Bob 25const arr = [1, 2, 3];
const [first, second] = arr;
console.log(first, second); // 1 2

解释: 从对象或数组中快速提取值赋给变量。


5. 默认参数

function greet(name = 'Guest') {console.log(`Hello, ${name}`);
}
greet();          // Hello, Guest
greet('Alice');   // Hello, Alice

解释: 函数参数可以设置默认值。


6. 展开运算符 ...

const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4];
console.log(arr2); // [1, 2, 3, 4]const obj1 = {a: 1, b: 2};
const obj2 = {...obj1, c: 3};
console.log(obj2); // {a:1, b:2, c:3}

解释: 展开数组或对象,合并或复制。


7. Promise 和 async/await 异步处理

// Promise
function fetchData() {return new Promise(resolve => {setTimeout(() => resolve('data'), 1000);});
}fetchData().then(data => console.log(data));  // data// async/await
async function asyncFetch() {const data = await fetchData();console.log(data);
}
asyncFetch();  // data

解释: 用 Promise 处理异步,async/await 语法更简洁。


8. 类(class)和继承

class Animal {constructor(name) {this.name = name;}speak() {console.log(`${this.name} makes a noise.`);}
}class Dog extends Animal {speak() {console.log(`${this.name} barks.`);}
}const d = new Dog('Rex');
d.speak();  // Rex barks.

解释: ES6 引入类语法,更接近传统面向对象。


9. 模块导入导出 importexport

// utils.js
export function sum(x, y) {return x + y;
}// main.js
import {sum} from './utils.js';
console.log(sum(2, 3));  // 5

解释: 支持模块化开发,导入导出代码片段。


10. Symbol 类型

const sym = Symbol('desc');
const obj = {};
obj[sym] = 'value';
console.log(obj[sym]);  // value

解释: Symbol 是一种独一无二的标识符,常用作对象属性键,避免命名冲突。


11. Map 和 Set 数据结构

const map = new Map();
map.set('a', 1);
console.log(map.get('a')); // 1const set = new Set([1, 2, 2, 3]);
console.log(set); // Set {1, 2, 3}

解释: Map 是键值对集合,Set 是无重复值的集合。


12. 生成器函数 function*

function* gen() {yield 1;yield 2;yield 3;
}const g = gen();
console.log(g.next().value); // 1
console.log(g.next().value); // 2

解释: 生成器可暂停执行,逐步产出值。


13. 可选链操作符 ?.

const obj = {a: {b: 10}};
console.log(obj.a?.b);     // 10
console.log(obj.x?.b);     // undefined 不报错

解释: 访问嵌套属性时安全,不会因中间值为 null 或 undefined 报错。


14. 空值合并运算符 ??

const foo = null ?? 'default';
console.log(foo);  // defaultconst bar = 0 ?? 42;
console.log(bar);  // 0

解释: 当左侧是 null 或 undefined 时,返回右侧值。

二、Javascript闭包

闭包(Closure)示例

function outer() {let count = 0;return function inner() {count++;console.log(count);}
}const counter = outer();
counter();  // 1
counter();  // 2
counter();  // 3

解释:

  • 函数 outer 返回了一个内部函数 inner

  • inner 函数可以访问 outer 的变量 count,即使 outer 已经执行完毕。

  • 这种函数和其访问的变量环境形成的组合,就叫闭包。

  • 闭包常用来实现私有变量和数据封装。

三、原型链

1.javascript原型链(经典函数构造器 + prototype)

function Person(name) {this.name = name;
}Person.prototype.sayHello = function() {console.log(`Hello, my name is ${this.name}`);
};const alice = new Person('Alice');
alice.sayHello();  // Hello, my name is Aliceconsole.log(alice.__proto__ === Person.prototype);  // true
console.log(Person.prototype.__proto__ === Object.prototype);  // true
console.log(Object.prototype.__proto__);  // null

解释:

  • 每个对象都有一个内部属性 [[Prototype]](常用 __proto__ 访问),指向它的原型对象。

  • 当访问对象的属性或方法时,如果自身没有,会沿着 [[Prototype]] 一层层往上找,这个查找链就是原型链

  • 上面例子中,alice 访问 sayHello 方法时没在自身属性里找到,就去它的原型对象 Person.prototype 查找。

  • Person.prototype 的原型是 Object.prototype,这构成了原型链的多层关系。

  • Object.prototype 的原型是 null,链条终点。

2.TypeScript 版本(class 语法)

class Person {name: string;constructor(name: string) {this.name = name;}sayHello() {console.log(`Hello, my name is ${this.name}`);}
}const alice = new Person('Alice');
alice.sayHello();  // Hello, my name is Aliceconsole.log(Object.getPrototypeOf(alice) === Person.prototype);  // true
console.log(Object.getPrototypeOf(Person.prototype) === Object.prototype);  // true
console.log(Object.getPrototypeOf(Object.prototype));  // null

解释:

  • TypeScript 使用 class 关键字声明类,语法更现代,代码更清晰。

  • sayHello 是类的方法,实际挂载在 Person.prototype 上,实例通过原型链访问。

  • Object.getPrototypeOf() 用来获取对象的原型,效果和 __proto__ 类似,但更标准安全。

  • 原型链关系和JavaScript版本完全一样:实例原型 → 类的 prototypeObject.prototypenull

3.总结

  • JavaScript版本用构造函数和显式原型,适合传统理解原型链机制。

  • TypeScript版本用类语法,更符合现代代码风格,本质上还是基于JavaScript原型链实现。

三、作用域链

作用域链简介

  • 作用域链是当访问一个变量时,JavaScript 引擎从当前作用域开始,逐级向上查找变量的过程。

  • 这保证了内层函数可以访问外层函数的变量。

  • 作用域链和原型链不同,作用域链是关于变量查找的执行环境机制。


1. JavaScript 版本示例

function outer() {const a = 10;function inner() {const b = 20;console.log(a + b); // 30}inner();
}outer();

解释:

  • inner 函数内部访问变量 a,它不在自身作用域中。

  • 于是它查找外层作用域 outer,找到了变量 a,然后计算并输出结果。

  • 这就是作用域链:innerouter → 全局。


2. TypeScript 版本示例

TypeScript 的作用域链机制和 JavaScript 一样:

function outer() {const a: number = 10;function inner() {const b: number = 20;console.log(a + b); // 30}inner();
}outer();

解释:

  • 语法和JavaScript几乎一致,只是变量类型显式声明了。

  • 作用域链机制完全相同,内层函数能访问外层函数的变量。


总结

  • 作用域链保证了变量从内层到外层逐级查找。

  • 它是运行时上下文环境的一部分,和闭包密切相关。

  • JavaScript 和 TypeScript 的作用域链规则一致,TS 只是加了类型。

四、如何使用 TypeScript 构建类型安全的 DApp 项目

下面给你关于“使用 TypeScript 构建类型安全的 DApp(去中心化应用)项目”的几个核心知识点,附带简短代码示例和解释。


1. 使用 TypeScript 定义智能合约接口类型

// 定义智能合约函数的接口
interface MyContract {methods: {balanceOf(address: string): { call(): Promise<string> };transfer(to: string, amount: string): { send(): Promise<void> };};
}

解释:
通过接口定义智能合约方法,确保调用时参数类型和返回类型明确,减少错误。


2. 使用 web3.js 或 ethers.js 连接以太坊并调用合约(示例用 ethers.js)

import { ethers } from 'ethers';async function getBalance(contract: MyContract, address: string): Promise<string> {const balance = await contract.methods.balanceOf(address).call();return balance;
}

解释:
函数参数用类型接口约束 contract,保证传入合约实例符合预期方法,address 是字符串。


3. 使用 TypeScript 定义事件类型并监听合约事件

interface TransferEvent {from: string;to: string;value: string;
}contract.on('Transfer', (from: string, to: string, value: string) => {const event: TransferEvent = { from, to, value };console.log('Transfer event:', event);
});

解释:
定义事件结构接口,事件监听回调参数用类型标注,方便后续类型检查和自动补全。


4. 使用类型安全的 ABI 绑定工具(如 TypeChain)

// 生成的合约类型(伪代码)
import { MyContract } from './types';const contract: MyContract = getContractInstance();const result = await contract.balanceOf('0x123...');

解释:
TypeChain 等工具根据合约 ABI 自动生成 TypeScript 类型,调用合约更安全,减少运行时错误。


5. 总结

  • 用 TypeScript 接口和类型定义合约方法和事件,保证调用和监听的类型安全。

  • 使用 ethers.js 或 web3.js 结合类型定义调用智能合约。

  • 通过 TypeChain 等工具生成合约类型代码,减少手写错误。

五、泛型

概念

泛型可以让函数、类或接口在使用时指定类型,而不是在定义时就固定死,提高了代码复用性和类型安全。

JavaScript 本身没有泛型,泛型是 TypeScript(以及其他静态类型语言)提供的类型系统特性,用来增强代码的类型安全和复用性。

简单来说:

  • JavaScript 是动态类型语言,变量和函数的参数类型在运行时确定,没有静态类型检查。

  • TypeScript 在 JavaScript 基础上加了类型系统,其中就包括泛型,可以在编译阶段帮你检查类型,避免运行时错误。

所以,泛型是 TypeScript 的特色,JavaScript 没有对应的语法和概念。

1. 泛型函数示例

function identity<T>(arg: T): T {return arg;
}const str = identity<string>('hello'); // str 类型是 string
const num = identity<number>(123);     // num 类型是 number

解释:

  • identity 是一个泛型函数,<T> 是类型参数,代表调用时传入的具体类型。

  • 传入参数和返回值类型都与 T 一致,调用时指定类型,保证类型安全且复用性强。


2. 泛型接口示例

interface Box<T> {value: T;
}const box1: Box<string> = { value: 'hello' };
const box2: Box<number> = { value: 100 };

解释:

  • Box 是一个泛型接口,成员 value 的类型由外部指定。

  • 方便用同一个接口定义不同类型的对象。


3. 泛型类示例

class Stack<T> {private items: T[] = [];push(item: T) {this.items.push(item);}pop(): T | undefined {return this.items.pop();}
}const stack = new Stack<number>();
stack.push(10);
console.log(stack.pop()); // 10

解释:

  • 泛型类 Stack 支持存放任何类型的元素,且保证类型一致性。

  • 实例化时指定具体类型,保证操作时类型安全。


4. 泛型约束示例

interface Lengthwise {length: number;
}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);return arg;
}loggingIdentity('hello'); // 输出 5
loggingIdentity([1, 2, 3]); // 输出 3
// loggingIdentity(123); // 报错,number 没有 length 属性

解释:

  • 泛型约束保证传入的类型必须有 length 属性。

  • 防止传入不符合约束的类型。

六、接口

概念

接口用于定义对象的结构,让代码更规范,可扩展性更好。

1. TypeScript 接口示例

interface User {id: number;name: string;email?: string; // 可选属性
}function greet(user: User) {console.log(`Hello, ${user.name}`);
}const user1 = { id: 1, name: 'Alice' };
greet(user1);

解释:

  • interface User 定义了一个结构类型,规定对象必须有 idnameemail 可选。

  • 函数 greet 形参要求是 User 类型,确保传入对象符合接口。


2. JavaScript 中模拟接口(无类型检查)

JavaScript 没有接口,但你可以用约定或运行时检查实现类似效果:

function greet(user) {if (typeof user.id !== 'number' || typeof user.name !== 'string') {throw new Error('Invalid user object');}console.log(`Hello, ${user.name}`);
}const user1 = { id: 1, name: 'Alice' };
greet(user1);

解释:

  • 通过函数内部手动检查对象属性类型,保证参数符合预期结构。

  • 但没有编译时类型检查,容易出错且不够方便。


总结:

  • TypeScript接口:静态类型检查,定义对象结构,是编译时用来提升代码健壮性的工具。

  • JavaScript:无接口概念,只能靠编码习惯和运行时检测保证对象结构。

应用场景

  • API 数据模型定义

  • 前后端数据类型统一

  • 高度协作项目中约定字段结构

七、装饰器

下面是 TypeScript 中的 装饰器(Decorator) 的讲解、使用条件、代码示例和解释。


📌 一、装饰器是什么?

装饰器是对类、方法、属性或参数的增强,是元编程的一种形式。需要在 tsconfig.json 中开启 experimentalDecorators

装饰器是 一种特殊的语法,用于 修改类、类方法、属性或参数的行为。它本质上是一个函数。

装饰器是 TypeScript 的高级功能之一,需要在 tsconfig.json 中启用

{"compilerOptions": {"experimentalDecorators": true}
}

🧪 二、类装饰器示例

function Logger(constructor: Function) {console.log('Class decorated:', constructor.name);
}@Logger
class User {constructor(public name: string) {}
}

✅ 解释:

  • @Logger 是一个类装饰器。

  • 它接收构造函数作为参数,在类定义时执行。

  • 装饰器不会改变类本身行为,但可以扩展、增强或者记录日志。


📦 三、方法装饰器示例

function LogMethod(target: any,propertyKey: string,descriptor: PropertyDescriptor
) {const original = descriptor.value;descriptor.value = function (...args: any[]) {console.log(`Method ${propertyKey} called with`, args);return original.apply(this, args);};
}class MathTool {@LogMethodadd(a: number, b: number) {return a + b;}
}const tool = new MathTool();
tool.add(2, 3); // 控制台打印日志

✅ 解释:

  • @LogMethod 修改 add 方法,使其在执行前打印参数。

  • 可以用于日志记录、性能分析、权限验证等。


🏷️ 四、属性装饰器示例

function ReadOnly(target: any, propertyKey: string) {Object.defineProperty(target, propertyKey, {writable: false,});
}class Person {@ReadOnlyname = 'Alice';
}const p = new Person();
// p.name = 'Bob'; // ❌ 会失败(只读)

✅ 解释:

  • @ReadOnly 将属性设置为只读。


📌 五、装饰器的应用场景

  • 日志打印(如方法调用参数)

  • 权限控制

  • 数据校验

  • 自动绑定(如 Vue、NestJS 中常见用法)

  • AOP(面向切面编程)

  • NestJS 控制器、服务模块增强

  • Web3 签名校验封装

http://www.xdnf.cn/news/931195.html

相关文章:

  • 数据库、数据仓库、数据中台、数据湖相关概念
  • MATLAB R2025a|Win中文|仿真建模|安装教程
  • uni-app学习笔记二十三--交互反馈showToast用法
  • Docker 安装 Ubuntu
  • day27-shell编程(自动化)
  • 附加模块--Qt Shader Tools功能及架构解析
  • typeof运算符 +unll和undefined的区别
  • AI书签管理工具开发全记录(十七):Sun-Panel书签同步实现
  • 【ArcGIS Pro微课1000例】0072:如何自动保存编辑内容及保存工程?
  • 68常用控件_QGroupBox的使用
  • C语言中的文件操作
  • Android写一个捕获全局异常的工具类
  • 【hive】函数集锦:窗口函数、列转行、日期函数
  • stm32-c8t6实现语音识别(LD3320)
  • 【Mac 从 0 到 1 保姆级配置教程 16】- Docker 快速安装配置、常用命令以及实际项目演示
  • 【SpringBoot+SpringCloud】Linux配置nacos踩坑大全
  • AI时代:学习永不嫌晚,语言多元共存
  • 思澈sdk-新建lcd
  • LeetCode--25.k个一组翻转链表
  • 从0开始学习R语言--Day20-ARIMA与格兰杰因果检验
  • 【第八篇】 SpringBoot高级配置(配置篇)
  • CZGL.SystemInfo:跨平台的系统信息获取库
  • AUTOSAR实战教程--DoIP_01_配置项解释
  • 0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化
  • Linux下GCC和C++实现统计Clickhouse数据仓库指定表中各字段的空值、空字符串或零值比例
  • Go基本语法——go语言中的四种变量定义方法
  • 【Java学习笔记】BigInteger 和 BigDecimal 类
  • 【Go语言基础【19】】接口:灵活实现多态的核心机制
  • 基于RT-DETR算法的夜间交通车辆与行人目标检测
  • FPGA静态功耗