在这里插入图片描述

肖哥弹架构 跟大家“弹弹” Javascript 设计与实战应用,需要代码关注

欢迎 关注,点赞,留言。

关注公号Solomon肖哥弹架构获取更多精彩内容

历史热点文章

📌 这是一份几乎涵盖所有JavaScript核心语法与高级特性的「硬核」汇总!无论你是正在入门的前端小白,还是想巩固知识体系的中高级开发者,这份指南都能让你大开眼界。内容包含:变量声明三大关键字对比 ✨、7种函数写法(含箭头函数、异步函数、柯里化)🔥、对象与数组的超实用技巧 🛠、ES6类与继承 🧩、Promise/Async异步编程指南 ⚡,以及可选链、空值合并等现代语法。附大量代码示例 + 实战用法,轻松提升你的JS内力!💻🎯

1. 变量与常量声明

关键字 作用域 是否可重新赋值 是否可重新声明 是否变量提升 初始值
var 函数作用域 ✅ Yes ✅ Yes ✅ (初始化为 undefined) 非必须
let 块级作用域 ✅ Yes ❌ No ❌ (暂时性死区 TDZ) 非必须
const 块级作用域 ❌ No (但对象/数组内容可修改) ❌ No ❌ (暂时性死区 TDZ) 必须

示例:

var oldVar = "I'm function scoped";
let modernLet = "I'm block scoped and reassignable";
const constantConst = "I'm block scoped and constant"; 

// const 声明的对象和数组内容可以修改(“可变”)
const person = { name: 'Alice' };
person.name = 'Bob'; // ✅ 允许
// person = { name: 'Charlie' }; // ❌ 报错:Assignment to constant variable.

const numbers = [1, 2, 3];
numbers.push(4); // ✅ 允许
// numbers = [5, 6, 7]; // ❌ 报错

2. 数据类型 (Primitives & Structural)

2.1 原始类型 (Primitive Types) - 按值访问

  1. undefined: 已声明但未赋值的变量。
  2. null: 表示空值( intentional absence of any object value)。
  3. Boolean: truefalse
  4. Number: 整数和浮点数(JS 只有一种数字类型)。包括 Infinity, -Infinity, NaN
  5. BigInt: 表示任意精度的整数(后缀加 n),例如 1234567890123456789012345678901234567890n
  6. String: 文本数据,可用单引号 ''、双引号 "" 或反引号 ` `
  7. Symbol: 唯一且不可变的值,常用作对象属性的键。

2.2 结构类型 (Structural Types) - 按引用访问

  1. Object: 各种键值对的集合。
    • Array: 特殊的有序对象,typeof [] // returns 'object'
    • Function: 可调用对象,typeof function() {} // returns 'function'
    • Date, RegExp, Map, Set, Promise 等。
      类型检查:
typeof 42; // "number"
typeof 'hello'; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof Symbol(); // "symbol"
typeof 123n; // "bigint"

// 注意历史遗留问题:
typeof null; // "object" (bug, but never fixed for legacy reasons)
typeof []; // "object"
typeof {}; // "object"
typeof function(){}; // "function"

// 更好的检查方法:
Array.isArray([]); // true
null instanceof Object; // false

3. 函数 (Functions)

3.1 函数声明 (Hoisted)

// 基本函数声明
function greet(name) {
  return `Hello, ${name}!`;
}
console.log(greet('Alice')); // Hello, Alice!

// 会提升 (可以在声明前调用)
console.log(square(5)); // 25
function square(x) {
  return x * x;
}

3.2 函数表达式 (Not Hoisted)

const greet = function(name) {
  return `Hello, ${name}!`;
};
// 基本函数表达式
const multiply = function(a, b) {
  return a * b;
};
console.log(multiply(3, 4)); // 12

// 命名函数表达式 (有助于调试)
const factorial = function fact(n) {
  return n <= 1 ? 1 : n * fact(n - 1);
};
console.log(factorial(5)); // 120

// 不会提升 (不能在声明前调用)
// console.log(divide(10, 2)); // Error
const divide = function(a, b) {
  return a / b;
};

3.3 箭头函数 (Arrow Functions) - ES6+

  • 更简洁的语法。
  • 没有自己的 thisargumentssupernew.target
  • 不能用作构造函数(不能用 new 调用)。
// 单个参数可省略括号
const square = x => x * x;

// 无参数需要括号
const sayHello = () => console.log('Hello!');

// 函数体有多条语句需用 {} 和 return
const multiply = (a, b) => {
  const result = a * b;
  return result;
};

// 返回对象字面量,需用括号包裹
const getPerson = () => ({ name: 'Alice', age: 30 });
// 基本语法
const add = (a, b) => a + b;
console.log(add(2, 3)); // 5

// 单个参数可省略括号
const double = x => x * 2;
console.log(double(5)); // 10

// 无参数需要括号
const getRandom = () => Math.random();
console.log(getRandom());

// 多行函数体需要大括号和 return
const calculate = (a, b, operation) => {
  const result = operation(a, b);
  return `Result: ${result}`;
};

// 返回对象字面量需要括号
const createUser = (name, age) => ({ name, age });
console.log(createUser('Bob', 25)); // {name: 'Bob', age: 25}

// 没有自己的 this(继承自外层作用域)
const person = {
  name: 'Alice',
  tasks: ['task1', 'task2', 'task3'],
  showTasks: function() {
    this.tasks.forEach(task => {
      console.log(`${this.name} needs to do: ${task}`);
    });
  }
};
person.showTasks();

3.4 参数默认值 & 剩余参数 (Rest Parameters) - ES6+

// 默认参数
function createUser(name, role = 'user', isActive = true) {
  // ...
}

// 剩余参数 (真数组,优于 arguments 对象)
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
sum(1, 2, 3, 4); // 10

3.5. 构造函数 (Constructor Functions)

// 构造函数(通常首字母大写)
function Person(name, age) {
  this.name = name;
  this.age = age;
  
  this.introduce = function() {
    return `Hi, I'm ${this.name}, ${this.age} years old`;
  };
}

// 使用 new 关键字创建实例
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);

console.log(person1.introduce()); // Hi, I'm Alice, 30 years old
console.log(person2.introduce()); // Hi, I'm Bob, 25 years old

// 在原型上添加方法(节省内存)
Person.prototype.getBirthYear = function() {
  const currentYear = new Date().getFullYear();
  return currentYear - this.age;
};

console.log(person1.getBirthYear()); // 当前年份 - 30

3.6. 异步函数 (Async Functions) - ES2017+

// 基本 async 函数
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
}

// 立即执行异步函数
(async () => {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error('Failed to fetch data');
  }
})();

// 异步箭头函数
const getUser = async (userId) => {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
};

// 并行执行多个异步操作
async function fetchMultipleData() {
  const [userData, postData, commentData] = await Promise.all([
    fetch('/api/users'),
    fetch('/api/posts'),
    fetch('/api/comments')
  ]);
  
  return {
    users: await userData.json(),
    posts: await postData.json(),
    comments: await commentData.json()
  };
}

// 异步生成器函数
async function* asyncNumberGenerator() {
  for (let i = 0; i < 5; i++) {
    await new Promise(resolve => setTimeout(resolve, 1000));
    yield i;
  }
}

(async () => {
  for await (const num of asyncNumberGenerator()) {
    console.log(num); // 每秒输出一个数字: 0, 1, 2, 3, 4
  }
})();

3.7. 高阶函数 (Higher-Order Functions)

// 返回函数的函数
function createMultiplier(multiplier) {
  return function(x) {
    return x * multiplier;
  };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15

// 接收函数作为参数的函数
function operateOnArray(arr, operation) {
  const result = [];
  for (const item of arr) {
    result.push(operation(item));
  }
  return result;
}

const numbers = [1, 2, 3, 4];
const squared = operateOnArray(numbers, x => x * x);
console.log(squared); // [1, 4, 9, 16]

// 函数组合
const compose = (...fns) => (x) => fns.reduceRight((acc, fn) => fn(acc), x);
const pipe = (...fns) => (x) => fns.reduce((acc, fn) => fn(acc), x);

const add5 = x => x + 5;
const multiply3 = x => x * 3;
const subtract2 = x => x - 2;

const composed = compose(subtract2, multiply3, add5);
const piped = pipe(add5, multiply3, subtract2);

console.log(composed(10)); // (10 + 5) * 3 - 2 = 43
console.log(piped(10));    // (10 + 5) * 3 - 2 = 43

// 记忆化函数 (Memoization)
function memoize(fn) {
  const cache = new Map();
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      console.log('Returning cached result');
      return cache.get(key);
    }
    const result = fn.apply(this, args);
    cache.set(key, result);
    return result;
  };
}

const slowFunction = (x) => {
  console.log('Computing...');
  return x * x;
};

const memoizedSquare = memoize(slowFunction);
console.log(memoizedSquare(5)); // Computing... 25
console.log(memoizedSquare(5)); // Returning cached result 25

3.8. 立即调用函数表达式 (IIFE)

// 基本 IIFE
(function() {
  console.log('IIFE executed immediately');
})();

// 带参数的 IIFE
(function(name) {
  console.log(`Hello, ${name}!`);
})('World');

// 箭头函数 IIFE
(() => {
  console.log('Arrow function IIFE');
})();

// 返回值
const result = (function(a, b) {
  return a + b;
})(10, 20);
console.log(result); // 30

// 模块模式(创建私有作用域)
const counter = (function() {
  let count = 0;
  
  return {
    increment: function() {
      count++;
      return count;
    },
    decrement: function() {
      count--;
      return count;
    },
    getCount: function() {
      return count;
    }
  };
})();

console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount());  // 2

3.9. 函数参数的高级用法

// 默认参数
function createUser(name, role = 'user', isActive = true) {
  return { name, role, isActive };
}
console.log(createUser('Alice')); // {name: 'Alice', role: 'user', isActive: true}

// 剩余参数 (Rest parameters)
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15

// 参数解构
function printUser({ name, age, email = 'N/A' }) {
  console.log(`Name: ${name}, Age: ${age}, Email: ${email}`);
}
printUser({ name: 'Bob', age: 25 }); // Name: Bob, Age: 25, Email: N/A

// 数组参数解构
function firstAndLast([first, , , last]) {
  return { first, last };
}
console.log(firstAndLast([1, 2, 3, 4, 5])); // {first: 1, last: 4}

// 参数标签(通过解构模拟)
function createElement({ tag = 'div', content = '', className = '' }) {
  return `<${tag} class="${className}">${content}</${tag}>`;
}

const element = createElement({
  tag: 'button',
  content: 'Click me',
  className: 'btn-primary'
});
console.log(element); // <button class="btn-primary">Click me</button>

3.10. 函数方法和属性

function example(a, b, c) {
  console.log('Function executed');
  console.log('this:', this);
  console.log('arguments:', arguments);
  console.log('name:', example.name);
  console.log('length:', example.length); // 期望的参数个数
}

// 调用函数
example(1, 2, 3);

// call, apply, bind 方法
const person = { name: 'Alice' };

function greet(greeting, punctuation) {
  return `${greeting}, ${this.name}${punctuation}`;
}

// call - 立即调用,逐个传递参数
console.log(greet.call(person, 'Hello', '!')); // Hello, Alice!

// apply - 立即调用,数组形式传递参数
console.log(greet.apply(person, ['Hi', '!!'])); // Hi, Alice!!

// bind - 返回新函数,延迟执行
const boundGreet = greet.bind(person, 'Hey');
console.log(boundGreet('...')); // Hey, Alice...

// toString 方法
console.log(greet.toString()); // 输出函数源代码

// 自定义函数属性
function counter() {
  counter.count = (counter.count || 0) + 1;
  return counter.count;
}

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter.count); // 2

3.11. 递归函数

// 基本递归
function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
console.log(factorial(5)); // 120

// 尾递归优化(某些引擎支持)
function factorialTail(n, acc = 1) {
  if (n <= 1) return acc;
  return factorialTail(n - 1, n * acc);
}
console.log(factorialTail(5)); // 120

// 递归处理嵌套数据结构
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (Array.isArray(obj)) return obj.map(deepClone);
  
  const cloned = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloned[key] = deepClone(obj[key]);
    }
  }
  return cloned;
}

const original = { a: 1, b: { c: 2, d: [3, 4] } };
const cloned = deepClone(original);
console.log(cloned); // {a: 1, b: {c: 2, d: [3, 4]}}

// 递归实现数组扁平化
function flattenArray(arr) {
  const result = [];
  for (const item of arr) {
    if (Array.isArray(item)) {
      result.push(...flattenArray(item));
    } else {
      result.push(item);
    }
  }
  return result;
}

const nested = [1, [2, [3, 4], 5], 6];
console.log(flattenArray(nested)); // [1, 2, 3, 4, 5, 6]

3.12. 柯里化函数 (Currying)

// 手动柯里化
function curryAdd(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
}
console.log(curryAdd(1)(2)(3)); // 6

// 通用柯里化函数
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...nextArgs) {
        return curried.apply(this, args.concat(nextArgs));
      };
    }
  };
}

const curriedSum = curry((a, b, c) => a + b + c);
console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6
console.log(curriedSum(1)(2, 3)); // 6

// 实际应用:创建特定功能的函数
const createLogger = prefix => message => console.log(`[${prefix}] ${message}`);
const errorLogger = createLogger('ERROR');
const infoLogger = createLogger('INFO');

errorLogger('Something went wrong!'); // [ERROR] Something went wrong!
infoLogger('Process completed');      // [INFO] Process completed

4. 对象 (Objects) - ES6+ 增强语法

4.1 属性简写 (Shorthand Property Names)

const name = 'Alice';
const age = 30;

// Old way
const person = { name: name, age: age };

// New way (ES6)
const person = { name, age }; // { name: 'Alice', age: 30 }

4.2 方法简写 (Shorthand Method Names)

// Old way
const obj = {
  greet: function() { ... }
};

// New way (ES6)
const obj = {
  greet() { ... } // 更简洁
};

4.3 计算属性名 (Computed Property Names)

const propKey = 'status';
const dynamicKey = Math.random() > 0.5 ? 'keyA' : 'keyB';

const obj = {
  [propKey]: 'active', // 属性名由变量计算得出
  [dynamicKey]: 'value',
  ['computed' + 'Key']: 'computed value'
};
// 结果可能是: { status: 'active', keyA: 'value', computedKey: 'computed value' }

4.4 解构赋值 (Destructuring Assignment)

从对象或数组中提取值到变量中。
对象解构:

const user = { id: 1, name: 'John', age: 25, email: 'john@example.com' };

// 提取特定属性
const { name, email } = user;
console.log(name); // 'John'

// 重命名变量
const { name: userName, age: userAge } = user;

// 默认值 (如果属性不存在或为 undefined)
const { phone = 'N/A', address } = user;

// 函数参数中解构
function printUser({ name, age }) {
  console.log(`${name} is ${age} years old`);
}
printUser(user);

数组解构:

const colors = ['red', 'green', 'blue'];

const [firstColor, secondColor] = colors;
console.log(firstColor); // 'red'

// 跳过元素
const [,, thirdColor] = colors; // thirdColor = 'blue'

// 默认值
const [a, b, c, d = 'yellow'] = colors; // d = 'yellow'

// 交换变量
let x = 1, y = 2;
[x, y] = [y, x]; // x = 2, y = 1

// 收集剩余元素
const [first, ...rest] = colors; // rest = ['green', 'blue']

5. 数组 (Arrays) - ES6+ 常用方法

5.1 扩展运算符 (Spread Operator) ...

// 复制数组 (浅拷贝)
const original = [1, 2, 3];
const copy = [...original];

// 合并数组
const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2]; // [1, 2, 3, 4]

// 将可迭代对象(如字符串)转为数组
const str = 'hello';
const chars = [...str]; // ['h', 'e', 'l', 'l', 'o']

5.2 迭代方法 (Iteration Methods)

const numbers = [1, 2, 3, 4, 5];

// .map() - 映射新数组
const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10]

// .filter() - 过滤数组
const evens = numbers.filter(n => n % 2 === 0); // [2, 4]

// .find() / .findIndex() - 查找元素/索引
const firstEven = numbers.find(n => n % 2 === 0); // 2
const firstEvenIndex = numbers.findIndex(n => n % 2 === 0); // 1

// .some() / .every() - 条件判断
const hasEven = numbers.some(n => n % 2 === 0); // true
const allEven = numbers.every(n => n % 2 === 0); // false

// .reduce() - 累积计算
const sum = numbers.reduce((acc, curr) => acc + curr, 0); // 15

// .forEach() - 遍历执行(无返回值)
numbers.forEach(n => console.log(n));

6. 字符串 (Strings) - ES6+ 模板字面量

6.1 模板字面量 (Template Literals) `...`

const name = 'Alice';
const age = 30;

// 字符串插值
const message = `Hello, my name is ${name} and I am ${age} years old.`;

// 多行字符串 (无需拼接符)
const multiLine = `
  This is a
  multi-line
  string.
`;

6.2 标签模板 (Tagged Templates) - 高级用法

function highlight(strings, ...values) {
  // strings: 模板中的静态字符串部分数组
  // values: 插值表达式计算后的值数组
  return strings.reduce((result, str, i) => {
    return result + str + (values[i] ? `<mark>${values[i]}</mark>` : '');
  }, '');
}

const name = 'Alice';
const age = 30;
const highlighted = highlight`Hello, ${name}! You are ${age}.`;
// 结果: "Hello, <mark>Alice</mark>! You are <mark>30</mark>."

7. 控制流 (Control Flow)

7.1 条件语句

// if...else
if (condition) {
  // ...
} else if (anotherCondition) {
  // ...
} else {
  // ...
}

// 三元运算符
const message = isMember ? 'Welcome back!' : 'Please sign up.';

// switch
switch (fruit) {
  case 'apple':
    console.log('🍎');
    break; // 必须 break,否则会继续执行下一个 case
  case 'banana':
    console.log('🍌');
    break;
  default:
    console.log('Unknown fruit');
}

7.2 循环语句

// for 循环
for (let i = 0; i < 5; i++) {
  console.log(i);
}

// for...of 循环 (遍历可迭代对象: Array, String, Map, Set等)
const arr = ['a', 'b', 'c'];
for (const item of arr) {
  console.log(item); // 'a', 'b', 'c'
}

// for...in 循环 (遍历对象的可枚举属性 - 通常用于对象,慎用于数组)
const obj = { a: 1, b: 2, c: 3 };
for (const key in obj) {
  console.log(key, obj[key]); // 'a' 1, 'b' 2, 'c' 3
}

// while / do...while
let i = 0;
while (i < 5) {
  console.log(i);
  i++;
}

let j = 0;
do {
  console.log(j);
  j++;
} while (j < 5);

8. 类 (Classes) - ES6 语法糖(基于原型)

class Person {
  // 构造函数
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  // 实例方法 (添加到 Person.prototype)
  greet() {
    return `Hello, my name is ${this.name}`;
  }

  // 静态方法 (直接存在于 Person 类上,不被实例继承)
  static compareAges(person1, person2) {
    return person1.age - person2.age;
  }

  // Getter
  get description() {
    return `${this.name} is ${this.age} years old`;
  }

  // Setter
  set newName(value) {
    if (value.trim() === '') {
      throw new Error('Invalid name');
    }
    this.name = value;
  }
}

// 继承
class Employee extends Person {
  constructor(name, age, jobTitle) {
    super(name, age); // 必须调用 super()
    this.jobTitle = jobTitle;
  }

  // 重写方法
  greet() {
    // 可以调用父类方法
    return super.greet() + ` and I'm a ${this.jobTitle}`;
  }
}

// 使用
const alice = new Person('Alice', 30);
const bob = new Employee('Bob', 25, 'Developer');
console.log(bob.greet()); // "Hello, my name is Bob and I'm a Developer"
console.log(Person.compareAges(alice, bob)); // 5 (静态方法)

9. 异步编程 (Asynchronous Programming)

9.1 Promise

表示一个异步操作的最终完成(或失败)及其结果值。

const fetchData = new Promise((resolve, reject) => {
  // 模拟异步操作
  setTimeout(() => {
    const success = Math.random() > 0.3;
    if (success) {
      resolve({ data: 'Here is your data!' }); // 成功
    } else {
      reject(new Error('Failed to fetch data')); // 失败
    }
  }, 1000);
});

// 使用 .then() .catch() .finally()
fetchData
  .then(response => {
    console.log('Success:', response.data);
    return processData(response.data); // 可以链式调用
  })
  .then(processedData => {
    console.log('Processed:', processedData);
  })
  .catch(error => {
    console.error('Error:', error.message);
  })
  .finally(() => {
    console.log('This runs regardless of success or failure');
  });

// Promise 工具方法
Promise.all([promise1, promise2, promise3]) // 全部成功才算成功
  .then(results => { /* results 是一个数组 */ });

Promise.race([promise1, promise2]) // 第一个 settled 的 promise
  .then(result => { /* ... */ });

Promise.any([promise1, promise2]) // 第一个成功的 promise
  .then(result => { /* ... */ });

9.2 Async/Await (基于 Promise 的语法糖)

用同步的方式写异步代码。

// async 函数总是返回一个 Promise
async function getData() {
  try {
    // await 会暂停执行,直到 Promise 被解决
    const response = await fetchData; 
    console.log('Success:', response.data);
    
    const processedData = await processData(response.data); // 可以继续 await
    console.log('Processed:', processedData);
    
    return processedData; // 等价于 Promise.resolve(processedData)
  } catch (error) {
    console.error('Error:', error.message);
    throw error; // 等价于 Promise.reject(error)
  }
}

// 调用 async 函数
getData().then(result => {
  console.log('Final result:', result);
});

10. 其他重要特性

10.1 可选链 (Optional Chaining) ?. - ES2020

在访问深层嵌套属性时,如果中间属性不存在,不会报错,而是短路返回 undefined

const user = {
  profile: {
    name: 'Alice',
    address: {
      city: 'New York'
    }
  }
};

// 传统方式(冗长)
const city = user && user.profile && user.profile.address && user.profile.address.city;

// 可选链(简洁安全)
const city = user?.profile?.address?.city; // 'New York'
const zipCode = user?.profile?.address?.zipCode; // undefined (不会报错)

// 也可用于函数调用和数组访问
const result = someObject?.someMethod?.();
const firstItem = someArray?.[0];

10.2 空值合并运算符 (Nullish Coalescing Operator) ?? - ES2020

如果左侧操作数是 nullundefined,则返回右侧操作数,否则返回左侧操作数。

const input = null;
const defaultValue = 'default';

const value1 = input || defaultValue; // 'default' (任何假值都会触发)
const value2 = input ?? defaultValue; // 'default' (只有 null/undefined 会触发)

const emptyString = '';
const zero = 0;

console.log(emptyString || 'default'); // 'default' (空字符串是假值)
console.log(emptyString ?? 'default'); // '' (空字符串不是 nullish)

console.log(zero || 42); // 42 (0 是假值)
console.log(zero ?? 42); // 0 (0 不是 nullish)

10.3 全局对象

  • 浏览器中: window
  • Node.js 中: global
  • ES2020 全局标准: globalThis (跨环境通用)
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐