是否缓存了数组的长度?

时间:2011-11-17 12:17:41

标签: javascript cross-browser

在JS中是缓存的数组的长度还是依赖于不同的引擎/浏览器?

通常情况下,我认为浏览器的JS引擎相当笨,并缓存了数组的长度,例如:

var a   = [ ];
var l   = l;

function arrayPush(i)
{
    l   = a.push( i );
}

function arrayPop()
{
    var r   = a.pop();

    l   = a.length;

    return r;
}

(作为一个简短的例子,当然复制每个数组函数都是愚蠢的,但如果它加速了它就值得了)

3 个答案:

答案 0 :(得分:2)

缓存数组长度。每次操作数组时都会更新。


当您在数组上调用.push()方法时,数组长度会在算法的第6步中更新:

  

使用参数“length”,n和true调用O的[[Put]]内部方法。

来源:http://es5.github.com/x15.4.html#x15.4.4.7


当您调用数组的.pop()方法时,数组长度会在算法的步骤5.d中更新:

  

使用参数“length”,indx和true调用O的[[Put]]内部方法。

来源:http://es5.github.com/x15.4.html#x15.4.4.6


在给定索引处为数组赋值时,将调用[[DefineOwnProperty]]内部方法。数组长度在算法的步骤4.e.ii中更新:

  

在A上传递“length”,oldLenDesc和false作为参数,调用默认的[[DefineOwnProperty]]内部方法(8.12.9)。此调用将始终返回true。

来源:http://es5.github.com/x15.4.html#x15.4.5.1

答案 1 :(得分:1)

正如在this answer中详细阐述的那样,现代浏览器将拥有能够非常合理地处理Array.length的JS引擎。

如果你担心它在较小的JS引擎上的性能,你可以缓存它,如果它将被重复使用,例如当在循环的停止条件下使用时。

for (var i = 0, arrLength = arr.length; i < arrLength; i++) { }

你需要保持自己的长度值(如你的例子所示),这是不太可能的。这不太可能给你带来任何明显的性能提升,但会使你的代码不易维护,更容易受到漏洞攻击。

答案 2 :(得分:0)

这取决于实现,虽然理智的浏览器应该只是维护一个计数器。如果它是一个非常差的实现,它可能必须遍历数据结构或某些东西来获得大小。

通常你会做这样的事情:

add(obj)
{
    buffer[ptr++] = obj;
}

getLength()
{
    return ptr;
}

当缓冲区为空时,ptr为0.添加对象会将其插入buffer[0]并将ptr增加1,这也将返回1。这意味着当您需要长度时,无需进行任何形式的“计数”操作。