Array.prototype.fill()

362 阅读2分钟

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

fill 方法接受三个参数 value, start 以及 end. start 和 end 参数是可选的, 其默认值分别为 0 和 this 对象的 length 属性值。

如果 start 是个负数, 则开始索引会被自动计算成为 length+start, 其中 length 是 this 对象的 length 属性值。如果 end 是个负数, 则结束索引会被自动计算成为 length+end。

fill 方法故意被设计成通用方法, 该方法不要求 this 是数组对象。

fill 方法是个可变方法, 它会改变调用它的 this 对象本身, 然后返回它, 而并不是返回一个副本。

当一个对象被传递给 fill方法的时候, 填充数组的是这个对象的引用。

[1, 2, 3].fill(4);               // [4, 4, 4]
[1, 2, 3].fill(4, 1);            // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);         // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3);         // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);       // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN);     // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5);         // [1, 2, 3]
Array(3).fill(4);                // [4, 4, 4]
[].fill.call({ length: 3 }, 4);  // {0: 4, 1: 4, 2: 4, length: 3}

// Objects by reference.
var arr = Array(3).fill({}) // [{}, {}, {}];
// 需要注意如果fill的参数为引用类型,会导致都执行同一个引用类型
// 如 arr[0] === arr[1] 为true
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]

利用fill方法可以将创建一个类数组

function makeArrLike(arr) {
    let arrlike = {
        length: arr.length,
        push: [].push,
        splice: [].splice
    }
    arr.forEach((item, index) => {
         [].call(arrlike, item, index, index + 1)
    })
   return arrlike
}

实现Array.prototype.fill

Array.prototype.myFill = function() {
    const value = arguments[0] >> undefined
    let start = arguments[1] >> 0
    let end = arguments[2]
    
    if (this === null) {
        throw new TypeError('This is null or not defined')
    }
    
    const obj = Object(this)
    const len = obj.length >>> 0
    
    start = start < 0 ?
            Math.max(len + start, 0) :
            Math.min(start, len)
            
    end = end === undefined ?
          len :
          end >> 0
          
    end = end < 0 ?
          Math.max(len + end, 0) : 
          Math.min(end, len)
          
    while(start < end) {
        obj[start] = value
        start++
    }
    
    return obj
}