[].slice.call(arguments)的理解

122 阅读3分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第5篇文章,[点击查看活动详情] (s.juejin.cn/ds/jooSN7t "s.juejin.cn/ds/jooSN7t"…

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

javascirpt的类数组对象可以像数组一样使用for循环遍历,但是却不能调用数组原型链的方法,为了让类数组对象可以像数组对象一样调用pushpop等方法,可以将类数组对象转成数组对象

  • 将类数组对象转换成数组
var args = []; 
var obj = {0:"www",1:"jianshu",2:"com",length:3};
for (var i = 0; i < obj.length; i++) { 
    args.push(obj[i]);
}
console.log(args);  //["www","jianshu","com"]

//等价于以下的写法
console.log([].slice.call(obj));  //["www","jianshu","com"]

理解[].slice.call(arguments)的原理,需要明白:

  • slice()方法的作用 Array.prototype.slice()
console.log([1,2,3,4,5].slice(0,1)); //[1]
console.log([1,2,3,4,5].slice(1,3)); //[2,3]
console.log([1,2,3,4,5].slice(3)); //[4,5]
console.log([1,2,3,4,5].slice()); //[1,2,3,4,5]

数组的slice(start,end)方法,返回从start开始到end的子数组,如果startend都没有设置,则返回整个数组,这个过程不影响原数组。

  • call()方法的作用 Function.prototype.call()
function func(name, price) {
  this.name = name;
  this.price = price;
}
var food = {name:"apple",price:10};
func.call(food,"orange",15);
console.log(food); // {name: "orange", price: 15}

调用call方法传入的参数比原方法多一个参数,简单来说,call方法的作用就是:用call方法的第一个参数代替func方法内部的this,其他参数为原func方法的参数。

slice 方法可以用来将一个类数组(Array-like)对象/[集合]转换成一个新数组。你只需将该方法绑定到这个对象上。 一个函数中的 arguments 就是一个类数组对象的例子。

[].slice.call(arguments)等价于:Array.prototype.slice.call(arguments) 和 [].__proto__.slice.call(arguments)

[].slice.call(arguments)

拆分一下

  • [] 数组,意思是创建一个空的数组对象
  • slice() :方法可从已有的数组中返回选定的元素。
  • 一般将 call 方法用于强制指定 this 的指向。
  • arguments 是一个类数组对象,是具有长度属性的,却并不是数组,不具备slice()这个方法,那就意味着 arguments.slice()行不通。
function array() {
  var _args = [].slice.call(arguments)// 将具有length属性的对象转换成数组
  console.log(_args)
}
 
array()
 
/**
 * 输出转换后的对象: []
 */

首先定义一个名为array的函数方法,在里面定义一个转换方法,arguments指向当前函数array的作用域,也就是方法内部,这个时候调用函数时是没有传递参数的,所以返回一个空数组,那么如果传递值呢?又是什么样子?

function array() {
  var _args = [].slice.call(arguments)// 将具有length属性的对象转换成数组
  console.log('输出转换后的对象:', _args)
}
 
array(5, 6, 7, 8, 9)
 
/**
 * 输出转换后的对象: [ 5, 6, 7, 8, 9 ]
 */

通过[]创建一个空数组,通过slice方法从已有的数组中返回选定的元素。

然后通过call()方法强制指定当前函数方法内部变量arguments,返回了函数参数列表,这个时候slice()方法将其解析,因为没有给slice参数start和end,所以直接返回从0到最后一个位置的所有参数,将这些参数内部push到[]这个创建好的空数组中,这样子就返回了一个数组元素!