2011-11-17 50 views
2

在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; 
} 

(作爲一個簡單的例子,當然,這將是愚蠢的,每複製陣列功能,但如果它加速它的東西了,那麼它是值得的)

+0

緩存到底在哪? – Oded

+0

@Oded - 很確定他正在談論計算長度vs長度計數器。 – Polynomial

+0

你能再詳細一點嗎?緩存是什麼意思?你是否問過每次f.e是否重新計算?如果你是在循環中獲得它? –

回答

2

數組長度被緩存。每次操作數組時都更新它。

調用[[把]]帶有參數的O內部方法「長度:


當調用陣列上的.push()的方法,所述陣列長度在算法的步驟6更新「,n,並且是真的。

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


當調用一個陣列的方法.pop(),陣列長度在算法的步驟5.D更新:

調用[[ Put]]的參數爲「length」,indx和true。

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


當一個給定的索引值分配給該陣列,該[[DefineOwnProperty]]內部方法被調用。陣列長度在算法的步驟4.e.ii更新:

調用默認[[DefineOwnProperty]]內部方法(8.12.9)上形成通過「長度」,oldLenDesc,假作爲參數。此調用將始終返回true。

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

+0

這是爲每個瀏覽器引擎? –

+0

@AhmedNuaman我(顯然)不知道某些瀏覽器在內部是如何工作的,但我認爲它們都實現了我答案中提到的內部算法。我想不出任何瀏覽器不這樣做的原因。 –

+0

哈哈哈,作爲理性的開發者,我們有很多瘋狂的東西,他們想知道爲什麼瀏覽器會這樣做,特別是某些公司的;) –

0

這取決於實施,雖然一個理智的瀏覽器應該簡單地維護一個計數器。如果這是一個非常糟糕的實現,它可能需要遍歷數據結構或其他東西來獲取大小。

通常情況下你會做這樣的事情:

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

getLength() 
{ 
    return ptr; 
} 

當緩衝區是空的,ptr爲0添加對象將其插入buffer[0]和增量ptr一個,它會返回1的長度也是。這意味着當你想要長度時,不需要進行任何形式的「計數」操作。

+1

存儲爲鏈接列表的數組?真? –

+0

@ShawnChin - 不,因爲那很愚蠢。因此,我爲什麼說「如果這是一個非常糟糕的實施」。 – Polynomial

+1

只是認爲這可能是誤導,尤其是對不熟悉的人。即「糟糕的實現」很可能指的是重複遍歷(而不是數據結構的選擇)。 –

1

正如在this answer中詳細闡述的那樣,現代瀏覽器將具有非常明智地處理Array.length的JS引擎。

如果您擔心它在較小的JS引擎上的性能,可以將其緩存,例如,如果它將被重複使用,例如,當用於循環的停止條件時。

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

它不太可能會這麼慢,你需要保持自己的長度值(如你的例子)。這不太可能會給您帶來明顯的性能提升,但會使您的代碼更易於維護,並且更容易受到漏洞的影響。