Array.prototype.slice.call(arguments,0)的实现

115 阅读1分钟

很多人经常用Array.prototype.slice.call(arguments, 0)来处理函数的参数,它本质是arguments想使用数组的slice这个方法返回一个新的数组,今天就来讲讲这段代码是如何来工作的。  
注意:

  1. Array是构造函数
  2. arguments是类数组对象(不是一个真正的数组,缺少很多数组的方法)
  3. call让一个对象调用另一个对象的方法。也可以用apply(),主要实现继承:写一个方法,然后让新的对象继承它而不是在新对象里再写一次这个方法
  4. slice从一个数组中切割,返回新的数组,不修改原数组

Array.prototype.slice.call(arguments, [0, arguments.length])

// 使用prototype只是因为Array是构造函数
Array.prototype.slice.call([0, 1, 2, 3, 4, 5], 0); // 输出 [0, 1, 2, 3, 4, 5]

[].slice.call([0, 1, 2, 3, 4, 5], 1); // 输出 [1, 2, 3, 4, 5]

// 如果是没有length的对象
let obj = {
    length: 2,
    0: 'first',
    1: 'second'
};
Array.prototype.slice.call(obj); // 输出 ['first', 'second']

Array.prototype.slice.call(obj, 1); // 输出 ['second']

let obj1 = {
    0: 'first',
    1: 'second'
};
Array.prototype.slice.call(obj1, 1); // 因为没有length,则截取到的是空数组,输出 []

 slice内部实现:  

Array.prototype.slice = function(start, end) {
    let result = new Array();
    start = start || 0;
    // this指向调用的对象,当用了call则改变this指向,this指向传进来的对象,这个关键!
    end = end || this.length; 
    for(let i = start; i< end; i++) {
        result.push(this[i]);
    }
    return result;
}

转成数组的通用函数:  

let toArray = function(value) {
    try {
        return Array.prototype.slice.call(value);
    } catch {
        let arr = [];
        for (let i = 0; i < value.length; i++) {
           // arr.push(value[i]);
           arr[i] = value[i]; // 这个快
        }
        return arr;
    }
}

转载于原文:www.cnblogs.com/papi/p/9234…