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

先放结论:[].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() 函数详解

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    千机楼阅读 945评论 0 4
  • Javascript有很多数组的方法,有的人有W3C的API,还可以去MDN上去找,但是我觉得API上说的不全,M...
    顽皮的雪狐七七阅读 2,118评论 0 4
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 5,181评论 2 17
  • 最近又开始懒于思考勤于发胖了,妈哒!说没时间是借口,有时候我会太沉溺于琐碎和细节,十几个小时悄咪咪过去,脑细胞阵亡...
    笨NANA阅读 30评论 0 0
  • ViewGroup的职能 Google官网上给出的ViewGroup的功能如下: A ViewGroup is a...
    Jackson杰阅读 164评论 0 2