2015-08-28 46 views
3

以從下面的例子: http://www.phpied.com/3-ways-to-define-a-javascript-class/Javascript:使用對象字面量時,屬性的排序很重要嗎?

var apple = { 
    type: "macintosh", 
    color: "red", 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' apple'; 
    } 
}; 

現在我移動的getInfo()方法在我的對象聲明的頂部。

var apple = { 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' apple'; 
    }, 
    type: "macintosh", 
    color: "red", 
}; 

apple.getInfo(); 
red macintosh apple 

我期待JavaScript解析器/編譯器失敗,因爲this.color和this.type尚未定義。這是如何在內部工作的?

(這個問題本來是一個ExtJS的框架問題在這裏:ExtJS: settings properties via a function on the Prototype: is it a safe pattern?,但我意識到這是一個更一般的JavaScript的問題,因此這個新)

+0

一旦你調用'apple.getInfo();'已經定義了整個蘋果對象。 – bumpy

+0

好問題,好問。 –

+0

即使您向該函數添加了永遠不會定義的屬性,解析器也不會失敗。這與JavaScript是[https://en.wikipedia.org/wiki/Duck_typing](Duck Typed))有關。 – Sam

回答

2

函數內部的代碼在調用之前不會被執行,因此this的屬性color在調用apple.getInfo()之前不會被執行。

編輯:

var apple = { 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' apple'; 
    }, 
    type: "macintosh", 
    color: "red", 
    } 
} 

此時蘋果對象被定義,並且getInfo屬性是將返回的屬性``當評價

apple.getInfo(); 
的函數

函數現在被評估,並且屬性IES colortype已清楚地已經在這一點上,當它被評估,從而如果屬性colortype改變時,函數的返回值的變化太

功能獲得這些屬性的值來定義。

+1

「此時蘋果對象被定義,並且getInfo屬性是一個函數,它將在評估時返回屬性」 這是我失蹤的一點,謝謝。 – Manu

2

所做的實例後調用該函數。在定義時,它不會運行,不會嘗試訪問屬性,但是在您調用函數的地方,它們全都存在。實際上,在解釋器解析各個屬性之間沒有辦法運行任何定製的JavaScript代碼。

0

我期待JavaScript解析器/編譯器失敗,因爲this.color和this.type尚未定義。

編譯器中的解析器不關心。 JavaScript不會評估是否可以找到屬性或變量,直到使用它的代碼是執行。在屬性的情況下,一個不存在的屬性只是被創建(如果你正在寫它)或者結果爲undefined(如果你正在讀取它),那麼即使你的對象沒有被創建,沒有colortype屬性,代碼仍然不會引發錯誤。你只會得到字符串"undefined undefined apple"

Javascript:使用Object literal時,屬性排序是否重要?

問題?可能不是。 有意義嗎?是的,截至ES6(aka ECMAScript 6 aka ECMAScript 20150),最新規範。對象初始值設定項中的屬性順序決定了屬性的創建順序,反過來又通過for-in循環部分設置它們的訪問順序,它們在Object.keys數組中顯示的順序等。(部分原因是屬性名稱可以強制整數的處理方式不同。)但是,您很少關心。在this answerthis answer(後者主要是關於數組,但觸及非數組對象的細節)。

+0

「*依次設置它們通過for-in循環訪問的順序*」。你確定?我沒有[*看到它聲明*](http://ecma-international.org/ecma-262/6.0/index.html#sec-for-in-and-for-of-statements)和[* Object.keys *](http://ecma-international.org/ecma-262/6.0/index.html#sec-object.keys)說:「***如果**實現定義了特定的枚舉順序for-in聲明...... *「(我強調)。 「如果」很重要。有很多引用「*以列表順序*」,但沒有定義對象屬性列表的順序(除了明顯的源順序外)。 – RobG

+0

有點混亂。內部[* Enumerate *方法說](http://ecma-international.org/ecma-262/6.0/index.html#sec-ordinary-object-internal-methods-and-internal-slots-enumerate)「*枚舉屬性的機制和順序沒有被指定,但必須符合下面指定的規則*「,然後[* OwnPropertyKeys *]()表示」* ...在屬性創建順序中... *「。猜猜我已經談過自己了。或者進入它。隨你。 – RobG

+0

@RobG:是的,我確定。許多引擎都在做這件事(但是對於索引風格的屬性與非索引風格的屬性,它們彼此略有不同),因此他們決定指定它。我會看看我是否可以追蹤我的答案,在那裏我拿出彎刀,並通過規範來弄清楚它是否屬實。 :-) –