V8引擎对Array.prototype.push的源码实现

时间:2022-07-25
本文章向大家介绍V8引擎对Array.prototype.push的源码实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一直非常困惑操作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属性。至于被修改的对象是谁,到底是数组还是类数组对象,这一点并不重要。

但是从以上代码可以看出这个对象至少满足:

  • 对象本书要可以存取属性
  • 对象的length属性可读写

参考资料:《Javascript设计模式与开发实践》