2017-02-19 59 views
2

我引用最近Google JavaScript Style GuideES5 getter和setter方法是「潛在的令人驚訝和難以推理」

不要使用JavaScript getter and setter properties。它們可能令人驚訝並且難以推理,並且對編譯器的支持有限。改爲提供普通的方法。

例外:在使用數據綁定框架(如Angular和Polymer)時,可以謹慎使用getter和setter。但是請注意,編譯器支持是有限的。使用它們時,必須在類或對象字面量中使用get foo()set foo(value)來定義它們,否則必須使用Object.defineProperties來定義它們。請勿使用Object.defineProperty,這會干擾屬性重命名。吸氣者不得改變可觀察的狀態。

非法:

class Foo { 
    get next() { return this.nextId++; } 
} 

這是谷歌的意見,但我想真正瞭解的原因。

首先,我認爲「編譯器」有一個有限的支持是Babel/Traceur/TypeScript?或者在某些ES5引擎中缺乏支持?

此外,我想了解什麼是「令人驚訝和困難」作者認爲的原因。我看到這些限制:

  1. Object.assign()不復制獲取者,但執行它們並複製值;
  2. 使用get name()語法,無法將getter添加到現有對象。對於現有對象,必須使用Object.defineProperty
  3. 用lambda定義一個getter是不可能的,這個限制可能導致我們在某些情況下使用舊學校let that = this

我不明白的語句:Object.defineProperty妨礙了物業更名」。 (什麼是「屬性重命名」?)

回答

3

我會假定他們的意思是:

「[潛在]奇」:與干將

屬性和setter方法不一定採取行動像正常的屬性。因此,他們違反了principle of least surprise。假設你有一個返回0,如果分配給它的值是負數的屬性:「[潛在]難推理」

myObj.prop = -7; 
expect(myObj.prop).to.equal(-7); // fails 

出於類似的原因。使用getter和setter的屬性不一定像普通屬性一樣工作,這意味着您不一定會以與正常屬性相同的方式推理它們。

假設我們再次具有上述屬性。你不能做到以下幾點:

myObj.prop = -7; 

console.log(myObj.prop * 9); 

// use substitution to figure out the result of the above statement: 

console.log(-7 * 9); // substitute -7 for myObj.prop 
console.log(-63);  // wrong - the above actually logs 0 

關於物業更名:根據this question,在Closure編譯器優化器會嘗試重命名(縮小)的屬性名稱,但它會通過重命名引用不完整的方式這樣做給他們,但不更新.defineProperty()電話。使用.defineProperties()允許優化器正確地重命名屬性。

+0

非常感謝,我現在明白了「物業更名」。關於「潛在的令人驚訝的事情」:我認爲這只是實現令人驚訝的時候?在你的例子中,二傳手應該拋出一個負數的例外,這個驚喜將會消失。我個人使用getters而不使用setter,以便懶惰地評估成員並使只讀(但是生活)屬性。不過,您的回答似乎是對Google推薦的一個很好的解釋。我等一會兒,然後我會驗證它。 – Paleo