v8引擎源码—Array.prototype.push实现详解

Table of Contents

具体实现如下:

function ArrayPush(){
    var n = TO_UINT32(this.length);  // 被push的对象的length
    var m = %_AraumentsLength();  // push的参数个数
    for(var i=0; i<m; i++){
        this[i+n] = %_Arguments(i);  // 复制元素  (1)
    }
    this.length = n + m;  // 修正length属性的值
    return this.length;
}

从上面的代码可以看出,Array.prototype.push实际上是一个属性复制的过程,把参数按照下标依次添加到被push的对象上面,同时修改了对象的length属性,不需要关注被修改的对象是数组还是类数组。 因此,我们可以把任意类型的对象传入到Array.prototype.push中,比如下面这个例子:

var a = {};
Array.prototype.push.call(a, "first", "second");
console.log(a);

观察上面这个例子我们发现如果要实现javascript中call和apply的区别与联系中”借用其他对象的方法”,需要满足下面的条件:

  1. 对象本身可以存取属性;

  2. 对象的length属性可读写;

本篇博客参考自JavaScript设计模式与开发实践,[p33-p34]