2021-04-18 18:46:22
在 JavaScript 中,使用 fill 方法可以高效地填充数组的某部分内容,但需注意其直接修改原数组的特性及对象引用的潜在问题。 以下是具体用法和注意事项:
1. 基本语法array.fill(value, start, end)
示例:
let arr = [1, 2, 3, 4, 5];arr.fill(0, 2, 4); // 从索引2到4(不包含4)填充0console.log(arr); // 输出: [1, 2, 0, 0, 5]2. 填充整个数组若省略 start 和 end,整个数组会被填充为指定值。
let arr2 = [1, 2, 3, 4, 5];arr2.fill(9); // 全部填充为9console.log(arr2); // 输出: [9, 9, 9, 9, 9]3. 填充对象时的引用问题fill 填充对象时,所有元素指向同一对象引用,修改其中一个会影响全部。
let obj = { a: 1 };let arr3 = new Array(3).fill(obj);console.log(arr3); // 输出: [{a: 1}, {a: 1}, {a: 1}]arr3[0].a = 2; // 修改第一个元素console.log(arr3); // 输出: [{a: 2}, {a: 2}, {a: 2}](全部被修改)解决方案:使用 map 或循环创建独立对象。
let arr4 = new Array(3).fill().map(() => ({ a: 1 }));arr4[0].a = 2;console.log(arr4); // 输出: [{a: 2}, {a: 1}, {a: 1}](仅第一个被修改)4. 避免修改原数组fill 会直接修改原数组,若需保留原数组,可先通过 slice() 创建副本。
let arr5 = [1, 2, 3, 4, 5];let newArr = arr5.slice().fill(0, 2, 4);console.log(arr5); // 输出: [1, 2, 3, 4, 5](原数组未变)console.log(newArr); // 输出: [1, 2, 0, 0, 5](新数组被修改)5. 初始化动态长度数组fill 可快速初始化长度为 n 的数组,填充默认值(如 null)。
let len = 10;let arr6 = new Array(len).fill(null);console.log(arr6); // 输出: [null, null, ..., null](长度为10)6. 配合 Array.from 生成特殊数组fill 可与 Array.from 结合,生成特定规则的数组。
// 生成 [0, 0, 0, 0, 0]let arr7 = Array.from({ length: 5 }).fill(0);console.log(arr7);// 生成 [1, 2, 3, 4, 5](通过映射函数)let arr8 = Array.from({ length: 5 }, (_, i) => i + 1);console.log(arr8);7. 处理稀疏数组fill 会填充稀疏数组中的所有空槽(empty items)。
let arr9 = new Array(5); // 稀疏数组: [ <5 empty items> ]arr9.fill(0);console.log(arr9); // 输出: [0, 0, 0, 0, 0]8. 兼容性与 Polyfillfill 是 ES6 特性,老版本浏览器需引入 Polyfill。Polyfill 示例:
if (!Array.prototype.fill) { Array.prototype.fill = function(value, start, end) { let O = Object(this); let len = O.length >>> 0; start = Math.max(start < 0 ? len + start : start, 0); end = Math.min(end === undefined ? len : (end < 0 ? len + end : end), len); for (let k = start; k < end; k++) { O[k] = value; } return O; };}9. 与 map 的区别总结:fill 是高效填充数组的工具,但需注意对象引用、原数组修改及兼容性问题。合理结合 slice、map 或 Array.from 可避免潜在陷阱。