ES6/ES11知识点 续四
数组
在 JavaScript(特别是 ES6+)中,数组操作非常丰富。以下是ECMAScript (ES) 中数组的常见操作汇总,包括创建、访问、修改、遍历、变换、过滤、查找、排序等——这是开发中必备的一套工具集合。
📦 创建数组
const arr = [1, 2, 3]; // 字面量
const arr2 = new Array(3); // 长度为3的空数组
const arr3 = Array.of(1, 2, 3); // [1, 2, 3]
const arr4 = Array.from('abc'); // ['a', 'b', 'c']
🔍 访问 & 基本属性
arr.length // 获取长度
arr[0] // 访问第一个元素
arr[arr.length - 1] // 最后一个元素
➕ 添加元素
arr.push(4); // 末尾添加
arr.unshift(0); // 开头添加
arr.splice(2, 0, 'a'); // 指定位置添加(索引2处插入'a')
➖ 删除元素
arr.pop(); // 删除末尾
arr.shift(); // 删除开头
arr.splice(1, 2); // 从索引1开始,删除2个元素
🔁 遍历数组
arr.forEach((item, i) => console.log(i, item));
for (const item of arr) console.log(item); // for...of
for (let i = 0; i < arr.length; i++) {} // 传统 for
🎨 变换数组
const mapped = arr.map(x => x * 2); // 映射
const filtered = arr.filter(x => x > 2); // 过滤
const reduced = arr.reduce((a, b) => a + b, 0); // 聚合
const flat = arr.flat(); // 展平多维数组(ES2019)
const flatMap = arr.flatMap(x => [x, x]); // 映射 + 展平
🧭 查找元素
arr.includes(3); // 是否包含
arr.indexOf(3); // 第一次出现的位置
arr.lastIndexOf(3); // 最后一次出现的位置
arr.find(x => x > 2); // 第一个符合条件的元素
arr.findIndex(x => x > 2);// 其索引
🔄 排序与反转
arr.sort(); // 字符串排序(注意数字会错误排序)
arr.sort((a, b) => a - b);// 数字升序
arr.reverse(); // 反转
🔀 复制与合并
arr.slice(1, 3); // 浅复制子数组,不含第3项
[...arr]; // 扩展运算符复制
arr.concat([4, 5]); // 合并数组
🛠️ 填充与替换
arr.fill(0); // 全部填充为 0
arr.fill(9, 1, 3); // 从索引1到3(不含)填充9
🧪 判断
Array.isArray(arr); // 是否为数组
arr.every(x => x > 0); // 所有元素满足条件
arr.some(x => x > 2); // 至少一个满足条件
📋 转换为字符串
arr.toString(); // 以逗号连接
arr.join('-'); // 使用自定义分隔符连接
✨ 新增方法(ES2023+)
arr.at(-1); // 获取最后一个元素(替代 arr[arr.length - 1])
arr.with(1, 99); // 替换索引1处的值为99,不改变原数组(ES2023)
🧩 其他常用技巧
[1, 2, 3].includes(2); // 是否包含某元素
Array.from({ length: 5 }, (_, i) => i); // 生成 [0,1,2,3,4]
将伪数组 转为 真正的数组
在 JavaScript 中,“伪数组”通常指的是具有 length 属性并且按索引访问元素,但不是 Array 实例的对象,比如:
• arguments
• NodeList
• HTMLCollection
• 字符串(可以类数组访问字符)
✅ 将伪数组转换为真数组的常用方法:
Array.from()
const realArray = Array.from(arrayLike);
✅ 推荐方式,语义清晰,兼容性好(ES6+)
扩展运算符 …
const realArray = [...arrayLike];
适用于可迭代对象(支持 Symbol.iterator),比如字符串、NodeList,但 不支持 arguments 在旧环境中。
使用 slice(旧方法)
const realArray = Array.prototype.slice.call(arrayLike);
兼容老浏览器,如 IE。适合 arguments 等无法直接使用扩展运算符的对象。
✅ 示例:将 arguments 转为数组
function test() {const args = Array.from(arguments); // 推荐// 或:const args = [...arguments]; // 错 ❌(arguments 不是可迭代)// 或:const args = Array.prototype.slice.call(arguments); // 兼容旧环境console.log(args);
}
Symbol
在 ES6 中,Symbol 是一种新的原始数据类型,表示独一无二的值。它常用于为对象定义唯一的属性键,避免属性名冲突。
🧱 基本语法
const sym = Symbol();
const sym2 = Symbol('描述');
- Symbol() 创建一个新的 symbol。
- 可选参数是仅用于调试的描述字符串,不会影响 symbol 的唯一性。
Symbol('foo') === Symbol('foo'); // false
🧩 用作对象属性键(私有属性)
const id = Symbol('id');
const obj = {[id]: 123
};console.log(obj[id]); // 123
🛠 常用于避免命名冲突
const obj = {name: 'Alice',[Symbol('name')]: 'Bob' // 不会冲突
};
🧾 获取 symbol 属性
- 默认的 for…in、Object.keys()、JSON.stringify() 都不会枚举 symbol 属性。
- 可以用这些方法获取:
Object.getOwnPropertySymbols(obj); // [Symbol(name)]
Reflect.ownKeys(obj); // 包括 string 和 symbol 的键
📚 全局 Symbol 注册表:Symbol.for
const sym1 = Symbol.for('key');
const sym2 = Symbol.for('key');sym1 === sym2; // true ✅
- Symbol.for() 会在全局 Symbol 注册表中查找已有 Symbol。
- Symbol.keyFor(sym) 返回全局注册的 key。
🚀 内置 Symbol(用于自定义语言行为)
Symbol | 用途说明 |
---|---|
Symbol.iterator | 定义对象的默认迭代器 |
Symbol.asyncIterator | 异步迭代器 |
Symbol.toStringTag | 自定义 Object.prototype.toString 的输出 |
Symbol.hasInstance | 自定义 instanceof 行为 |
Symbol.toPrimitive | 自定义类型转换 |
Symbol.match | 自定义 String.prototype.match 行为 |
Symbol.replace | 自定义 replace 行为 |
示例:
const obj = {[Symbol.toPrimitive](hint) {return hint === 'number' ? 42 : 'hello';}
};
+obj; // 42
✅ 典型应用场景
- 定义私有或唯一的属性
- 插件/库扩展对象时避免属性冲突
- 自定义类行为(如迭代器、类型转换)
使用 Symbol.iterator 让普通对象变得可迭代
const range = {start: 1,end: 5,[Symbol.iterator]() {let current = this.start;const end = this.end;return {next() {if (current <= end) {return { value: current++, done: false };} else {return { done: true };}}};}
};for (const num of range) {console.log(num);
}
// 输出:1 2 3 4 5