[].slice.call(arguments)原理解析

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()方法的作用
  • call()方法的作用
  • 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都没有设置,则返回整个数组,这个过程不影响原数组。

  • 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方法内部实现
    slice方法内部实现,V8源码第587行,其基本原理就类似我们上面开头写的for循环遍历原数组,根据start和end的值再复制一份到新数组并返回。所以当我们使用[].slice.call(arguments),slice方法内部的this就会被替换成arguments,并循环遍历arguments,复制到新数组返回,这样就得到了一个复制arguments类数组的数组对象。

  • 为了提高性能,减少一层对原型链的追溯,一般我们会采用以下的写法

Array.prototype.slice.call(arguments)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,199评论 0 13
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,270评论 0 4
  • 小时候我在一条狭长的弄堂里长大。 街坊邻居们都非常和睦,当然这也有可能只是表面上的。谁家煮了肉,谁家炖了鸡,总是端...
    不会飞的聪明鸟阅读 220评论 0 0
  • 所有天气,我最喜欢的是雨天,不为什么,就因为它有我喜欢的铁灰色,以及应该懂得的哲理...... ——题记 看着那片...
    清酒无欢阅读 358评论 0 0
  • 2017.4.30 说她 今天又和你谈到异性朋友之间的关系,你如何看待你和一个异性朋友之间的感情,是单纯的友谊吗?...
    破书残画丶阅读 113评论 0 1