美文网首页前端Web前端之路让前端飞
你遇到过[ ].slice.call()吗?

你遇到过[ ].slice.call()吗?

作者: hanyuntao | 来源:发表于2017-04-19 09:55 被阅读181次

    先放结论:[].slice.call(arguments)能将具有length属性的对象转成数组。

    Paste_Image.png

    1、基础知识

    • .slice()方法
      • 定义和用法
        slice(start, end) 方法可提取数组的某个部分,并以新的数组返回被提取的部分。
        使用start(包含) 和 end(不包含) 参数来指定提取数组开始和结束的部分。

        • 如果未指定start和end,则返回整个数组。
        • 如果指指定一个参数,该参数作为start使用,返回包括start位置之后的全部数组。
        • 如果是负数,则该参数规定的是从数组的尾部开始算起的位置。也就是说,-1 指数组的最后一项,-2 指倒数第二个项,以此类推。
      • 实例

    //在数组中读取元素:
    var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
    var citrus = fruits.slice(-3,-1);
    citrus 结果输出:
    ["Lemon", "Apple"]
    
    • .call()方法
      • 定义和用法
        call()函数用于调用当前函数functionObject,并可同时使用指定对象thisObj作为本次执行时functionObject函数内部的this指针引用。
      • 实例
    var obj = {name: "李四", age: 20};
    function foo(a, b){
        document.writeln(this.name);    
        document.writeln(a);    
        document.writeln(b);    
    }
    // 改变this引用为obj,同时传递两个参数
    foo.call(obj, 12, true); // 李四 12 true
    

    2.进入正题

    当我看到var args = [].slice.call(arguments, 0);这种写法的时候是一脸懵逼的(黑人问号脸)。
    arguments是一个对象而不是数组,最多算是一个伪数组,而且自身的原型链上也没有slice这个方法。

    /*确定arguments的类型
        * 返回 3,Object, true;
        */
        (function(a,b,c){
           console.log(arguments.length);
           console.log(typeof arguments);
           console.log( arguments instanceof Object);
    
        }(1,2,3))
    

    [].slice.call(arguments)能将具有length属性的对象转成数组:

    • []自身也是也是一个对象.而数组原型链上有这个slice这个方法。
     /*此处的返回值是true*/
       [].slice === Array.prototype.slice;
    
    • 通过call显式绑定来实现arguments变相有slice这个方法。
    • 这就是说:Array.prototype.slice.call(arguments,0)这句里,就是把 arguments 当做当前对象
      也就是说 要调用的是 argumentsslice 方法,后面的 参数 0 也就成了 slice 的第一个参数,slice(0)就是获取所有。

    **补充: **
    将函数的实际参数转换成数组的方法

    方法一:var args = Array.prototype.slice.call(arguments);

    方法二:var args = [].slice.call(arguments, 0);

    方法三:

    var args = []; 
    for (var i = 1; i < arguments.length; i++) { 
        args.push(arguments[i]);
    }
    

    最后,附个转成数组的通用函数

    var toArray = function(s){
        //try语句允许我们定义在执行时进行错误测试的代码块。
       //catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
        try{
            return Array.prototype.slice.call(s);
        } catch(e){
            var arr = [];
            for(var i = 0,len = s.length; i < len; i++){
                //arr.push(s[i]);
                   arr[i] = s[i];  //据说这样比push快
            }
             return arr;
        }
    }
    

    参考资料:
    Array.prototype.slice.call()方法详解
    对[].slice.call(arguments,1) 的一丢丢见解
    JavaScript arguments对象
    JavaScript Function.call() 函数详解

    相关文章

      网友评论

      • d93fcad66401:这家店好评,店主说的很详细,一个字一个字的敲出来,居然连slice方法都详细的说明,五星好评!:kissing_heart:
        hanyuntao:@JS_Potato 谢谢你

      本文标题:你遇到过[ ].slice.call()吗?

      本文链接:https://www.haomeiwen.com/subject/mgjczttx.html