2014-01-25 112 views
7

在閱讀此http://www.html5rocks.com/en/tutorials/speed/v8/時,有必要在運行時更改變量類型,以使瀏覽器比保持一致時更努力地工作。Javascript聲明變量 - 最佳做法

這是否意味着這不是一個好主意:

var x = { 
    alpha: null, 
    bravo: null, 
    charlie: null, 
    delta: null, 
    echo:  null 
} 

x.alpha = {a:1, b:true} 
x.bravo = 13 
x.charlie = true 
x.delta = [1,2,3] 
x.echo = 'abc' 

因爲這裏的類型開始爲空,然後得到了改變反對,整型,布爾arrary。

並且爲了簡單起見,事後這些類型從不改變。

或者,這是更有效的:

var x = { 
    alpha: {}, 
    bravo: 0, 
    charlie: false, 
    delta: [], 
    echo:  '' 
} 

x.alpha = {a:1, b:true} 
x.bravo = 13 
x.charlie = true 
x.delta = [1,2,3] 
x.echo = 'abc' 

我能理解改變類型比如從一數到一個數組是不是一個好主意。如何在執行期間從null更改爲類型一次?

我讀過的書籍和博客大多數都會說,只有在運行時才知道這些值,才能用null定義變量(而不是未定義)。在面值時,這看起來是錯誤的,因爲用它們的空類型定義避免了類型變化。

+0

空是對象類型 –

+0

這是很好的,因爲它是一個更容易檢查,如果事情是零,而不是{} –

+0

其實你無法對證{},那麼你可以,但你總是會得到錯誤的,因爲即時創建新對象,例如{} === {}的計算結果爲false。 –

回答

6

好奇的在這個問題中,我設置了一個小竅門來查看一些不同用例的性能。

打開控制檯,在這個小提琴查看數據
http://jsfiddle.net/kmiklas/MFNak/14/

  • 人們似乎沒有初始化之間的差別不大,初始化爲null,並初始化爲數字。
  • 除數字外,通過將變量初始化爲預期類型(原始帖子中的第二個示例)會導致性能損失。
  • 從這些數據可以看出,初始化爲無效是最好的選擇。從瀏覽器V32

典型結果,其中n =億:

number no init: 97.070ms 
number init to null: 98.023ms 
number init to number: 97.246ms 
array no init: 457.494ms 
array init to null: 458.301ms 
array init to number: 455.166ms 
array init to array: 836.710ms 
object no init: 508.268ms 
object init to null: 512.312ms 
object init to object: 754.562ms 
number to object: 455.733ms 
array to object: 834.169ms 
object to array: 751.498ms 
~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

代碼相當冗長的,但包括下面,每SO要求。

n = 100000000; 
console.time("number no init"); 
    for (var i = n; i >= 0; i--) { var x; x = 42; }; 
console.timeEnd("number no init"); 

console.time("number init to null"); 
    for (var i = n; i >= 0; i--) { var x = null; x = 42; }; 
console.timeEnd("number init to null"); 

console.time("number init to number"); 
    for (var i = n; i >= 0; i--) { var x = 1; x = 42; }; 
console.timeEnd("number init to number"); 

console.time("array no init"); 
    for (var i = n; i >= 0; i--) { var a; a = [42]; }; 
console.timeEnd("array no init"); 

console.time("array init to null"); 
    for (var i = n; i >= 0; i--) { var a = null; a = [42]; }; 
console.timeEnd("array init to null"); 

console.time("array init to number"); 
    for (var i = n; i >= 0; i--) { var a = 1; a = [42]; }; 
console.timeEnd("array init to number"); 

console.time("array init to array"); 
    for (var i = n; i >= 0; i--) { var a = []; a = [42]; }; 
console.timeEnd("array init to array"); 

console.time("object no init"); 
    for (var i = n; i >= 0; i--) { var a; a = {n:42}; }; 
console.timeEnd("object no init"); 

console.time("object init to null"); 
    for (var i = n; i >= 0; i--) { var a = null; a = {n:42}; }; 
console.timeEnd("object init to null"); 

console.time("object init to object"); 
for (var i = n; i >= 0; i--) { var a = {}; a = {n:42}; }; 
console.timeEnd("object init to object"); 

console.time("number to object"); 
    for (var i = n; i >= 0; i--) { var a = 1; a = {n:42}; }; 
console.timeEnd("number to object"); 

console.time("array to object"); 
    for (var i = n; i >= 0; i--) { var a = []; a = {n:42}; }; 
console.timeEnd("array to object"); 

console.time("object to array"); 
for (var i = n; i >= 0; i--) { var a = {}; a = [42]; }; 
console.timeEnd("object to array"); 
console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~'); 
+0

完美!因此init爲null是要走的路,也很容易檢查if語句。所以書和博客都是正確的。 –

+1

請記住,我只在Chrome 32中測試過。要準確地得出這個結論,最好加載這個小提琴並在更流行的桌面和移動瀏覽器中看到結果;特別是IE和Safari Mobile。 – kmiklas

3

在初始化時,所有javascript變量都會被提升到範圍的頂部,值爲undefined。直到分配變量的值才能分配特定的類型。

所以你在這裏做的是有效地重新分配變量的值和類型兩次。性能成本可能可以忽略不計,但是優選實踐中來聲明一個對象,其值不知道的是一個對象文本:

var x = {}; 

如果您嘗試訪問不存在的對象的屬性,你會得到未定義的(這與測試null一樣容易)。但是,如果像你說的屬性已知,那麼運行時沒有理由不分配這些屬性馬上之前,所以......

x.alpha = {a:1, b:true} 
x.bravo = 13 
x.charlie = true 
x.delta = [1,2,3] 

成爲...

var x = { 
    alpha: {a:1, b:true}, 
    bravo: 13, 
    charlie: true, 
    delta: [1,2,3] 
}; 
+0

我不認爲這就是問題所在...... –

+0

大部分時間我都不知道這些變量的值直到運行時。我知道類型不會改變。所以即使你知道後面的代碼中它將是一個整數,所有未知的變量都應該被聲明爲{}。 –

+0

不,只有您知道的變量將成爲稍後將分配屬性的對象。如果你不知道類型是什麼,你可以聲明一個沒有值的變量,'var x;' – monners