Array.prototype.slice.call(obj, 0);是什么意思?

188 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

这本质是slice()函数和call()函数的一个组合应用

①、slice()是数组对象的固有方法,用来截取数组

例子:有数组arr=[2,3,4,5];

arr.slice(0);   //输出:2,3,4,5

arr.slice(1,3);   //输出3,4  即从下标1开始,到下标3的前一个结束

\

②、call()方法,能够改变函数的this指向

这个方法就很有意思,它给我的感觉就是能把一个对象的方法借给别人,同时将自己方法中的原本指向自己的this,改成指向别人

\

例子:

      let objNokia = {
            name: 'Nokia',
            price: 399,
            character: '砸核桃',
            show: function () {
                console.log(this.name + '手机,只要' + this.price + ',能' + this.character)
            }
        }
        let objXiaoMi = {
            name: 'XiaoMi',
            price: 2999,
            character: '当暖手宝'
        }
        objNokia.show.call(objXiaoMi);

objNokia.show.call(objXiaoMi) //输出:XiaoMi手机,只要2999,能当暖手宝

\

例子中小米和诺基亚有类型的数据结构,不同的是小米没有展示show这个方法,但是没关系,使用show.call(obj)可以将show方法借给obj使用,call会立即执行show函数,并且函数中的this指向改为obj

米:你的方法很棒,不如call(copy)给我吧

歪嘴.PNG

\

、call的参数。第一个参数是借予的目标对象,后面的参数则传递给被借出去的源方法

Array.prototype.slice.call(obj, 0);能将伪数组obj转换成真正的数组

 Array.prototype.slice.call(obj, 1,4); 先将伪数组转换成数组后,截取下标1~3的元素作为数组返回 

事实上就是obj之后的参数被传递给了slice函数 

\

为什么是Array.prototype.slice.call(obj, 0);

obj是个伪数组, 虽然自身没有数组的slice的方法,但得益于和数组有类似的数据结构,通过call借来数组的slice方法它可以完美适用(直接牛过来hhh)

但比起slice方法原本的功能(剪切数组),它的副作用才是我们的目标。运行一次slice后,它将伪数组转换成了真正的数组返回了过来,这可比for循环舒服多了

\

*再多想一步,如果考虑兼容性

可以这样写

       function turnToArray(obj) {
            try {
                return Array.prototype.slice.call(obj);
            } catch (e) {
                let arr = [];
                for (let index = 0; index < obj.length; index++) {
                    const element = obj[index];
                    arr.push(element)
                }
                return arr;
            }
        }

与apply函数的关系

call与apply都可以借用函数,使用方法是一样的,函数的第一个参数都是方法借予的对象,区别在于后面的参数。

call第一个参数后可以写任意个,且都会传给借用的方法。

而apply的第二个参数是一个数组,里面是要传给方法所有的参数

例子:

let obj={
    0:'a',
    1:'b',
    2:'c',
    3:'d',
    length:4
};
Array.prototype.slice.call(obj, 0,3) //复制到Chrome控制台中,输出['a','b','c']
Array.prototype.slice.apply(obj, [0,2]) //复制到Chrome控制台中,输出['a','b']

欢迎任何留言!交流使人进步!