一直非常困惑操作arguments的时候为什么都要用Array.prototype,今天终于明白了。
函数的参数列表 arguments 是一个类数组对象,虽然他也有“下标”,但它并非真正的数组,所以也不能向数组一样,进行排序操作或者往集合中添加一个新的元素。
通常会借用Array.prototype.push:
(function(){
Array.prototype.push.call(arguments, 3);
console.log(arguments);
})()
在操作arguments的时候,经常非常频繁的找Array.prototype对象借用方法。
想把arguments 转成真正的数组的时候,可以借用Array.prototype.slice方法;想截取arguments列表中的头一个元素时,又可以借用Array.prototype.shift方法。那么内部实现原理是什么?让我们来看看V8的引擎源码,以Array.prototype.push为例,看看V8引擎中的具体实现:
function ArrayPush(){
// 被push的对象的长度;this指向了调用他的对象
var n = TO_TNIY32( this.lengtt );
// push的参数个数
var m = %_ArgumentsLength();
for (var i=0; i < m; i++){
// 复制元素
this[ i + n ] = %_arguments( i );
}
this.length = n + m;
return this.length;
}
以上,Array.prototype.push实际是一个属性复制的过程,把参数按照下标依次添加到被push的对象上面,顺便修改这个对象的length属性。至于被修改的对象是谁,到底是数组还是类数组对象,这一点并不重要。
但是从以上代码可以看出这个对象至少满足:
参考资料:《Javascript设计模式与开发实践》