[].slice.call(arguments)将arguments类数组转换为数组的的实现原理

[].slice.call(arguments)作用:把arguments转换为数组。
等同于[...arguments]。
那么内部实现原理呢?
这里就需要先清楚数组的slice()和函数的call(obj,arg1,arg2,...)的实现原理。

首先了解下call()方法:
Function.call(obj,arg1,arg2,...)的作用:把Function内部的this指向obj这个对象。

举例看看:
function test(){
   console.log(this) // {a: 1, b: 2}
}
const obj = {
   a:1,
   b:2
}
test.call(obj)
//从输出结果来看,确实是指向了obj对象
//那我给test()加个属性看看
function test(name){
   this.name = name
   console.log(this) // {a: 1, b: 2, name: "yy"}
}
const obj = {
   a:1,
   b:2
}
test.call(obj,'yy')
//从结果可看到,此时this指向的并不是obj这个对象,而是由函数内部的属性、方法(如果有的话)与obj对象内部的属性、方法组成的新对象。
//所以call()的作用得修正过来,并不是指向的是那个传入的obj对象,而是一个新的obj对象。

再来看下:数组的slice()。

//这是一个简洁版的slice()内部实现过程。
Array.prototype.slice=function(start,end){  
    let result = new Array(); //创建一个新数组
    let start = start || 0;
    let end = end || this.length; //this指向的是调用slice()的数组
    for(let i=start; i<end; i++){
        result.push(this[i]);
    }
    return result;  //返回一个新的数组
}

slice()内部会去遍历数组内的每一个元素(前提是没有传入start参数、end参数),把遍历到的元素存放到一个空数组,遍历结束,再把这个空数组返回。作用有点像拷贝。

当把slice()与call()结合后,由于call()的作用,slice()内部的this指向了新的对象。
看下面的例子。

Array.prototype.slice=function(start,end){  
    let result = new Array(); //创建一个新数组
    let start = start || 0;
    let end = end || this.length; //this指向发生改变
    for(let i=start; i<end; i++){
        result.push(this[i]);
    }
    return result;  //返回一个新的数组
}

function fn(){
    let res = [].slice.call(arguments) /
    console.log(res)//[1,2,3]
}
fn(1,2,3)

arguments:是个类数组,但是也有length属性,所以在slice()内部可以对arguments进行遍历,把arguments内部的元素遍历后,组成数组返回。所以最后呈现给我们的结果就是把arguments转变为了数组。

最后我想说明一点:在上面的例子中slice()内部的this在call()的作用指向了arguments,看似是这样,但是我给slice()内部额外加个属性试试:

Array.prototype.slice=function(name,start,end){  
    this.name = name //额外添加的属性
    let result = new Array(); //创建一个新数组
    let start = start || 0;
    let end = end || this.length; //this指向发生改变,但并不指向原来的arguments,
    //严格来讲,是经过组合得到的新arguments
    console.log(this)//[1, 2, 3, name: "yy",...]
    for(let i=start; i<end; i++){
        result.push(this[i]);
    }
    return result;  //返回一个新的数组
}

function fn(){
    let res = [].slice.call(arguments,'yy') 
    console.log(res)//[1,2,3]
}
fn(1,2,3)

最近又看到Array.prototype.slice.call( arguments, 0 ),arguments后面又加了个数字。但是,理解不了这个数字是怎么起作用的。

 var my_object = {
    '0': 'zero',
    '1': 'one',
    '2': 'two',
    '3': 'three',
    '4': 'four',
    length: 5
};
var sliced0 = Array.prototype.slice.call( my_object, 0 );
var sliced1 = Array.prototype.slice.call( my_object, 1);
var sliced2 = Array.prototype.slice.call( my_object, 2);
console.log(sliced0)//["zero", "one", "two", "three", "four"]
console.log(sliced1)//["one", "two", "three", "four"]
console.log(sliced2)//["two", "three", "four"]

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容