3

JavaScript設置器更新引用的內部值,但返回值不正確。JavaScript設置器無需驗證就返回值

var Game = 
{ 
    get points() { 
     return this._points; 
}, 

    set points(x){   
     x = Math.min(x,25); 

     this._points = x; 
     return this._points; 
    } 
}; 

Game.points = 10 ; 

console.log(Game.points); // outputs 10 

var updatedPoints = (Game.points = 60); 

console.log(updatedPoints); // outputs 60 
console.log(Game.points); // outputs 25 

'updatedPoints'的預期值是25!

任何想法爲什麼會發生這種情況?你能否建議是否有辦法解決這個問題?

解決此問題的原因:爲了確保JS代碼按預期執行,可維護性!

+0

@FelixKling人們會認爲updatedPoints的值是25? – sbr

+0

是的,我現在明白你的問題。但是,不,分配表達式的結果是分配的值(即60)。 –

+0

我會使用逗號運算符 - 它更短:P var updatedPoints =((Game.points = 60),Game.points); –

回答

6

JavaScript簡單分配(=)根據規範返回正確的值(11.13.1)。這種行爲會忽略在你的setter中發生的任何驗證。

從規格:

生產AssignmentExpressionLeftHandSideExpression = AssignmentExpression如下評價:

  1. LREF是評估LeftHandSideExpression的結果
  2. rref是評估結果AssignmentExpression
  3. rval成爲GetValue(rref)。
  4. 投擲的SyntaxError異常,如果以下所有條件,則:
    • 類型(LREF)是參考是
    • IsStrictReference(LREF)是
    • 類型(GetBase(lref))是環境記錄
    • GetReferencedName(LREF)或者是 「EVAL」 或 「參數
  5. 呼叫PutValue(LREFRVAL)。
  6. 返回rval

所以沒有辦法「修理」你的問題,因爲它是由設計。檢查Game.points應該足夠了。

+0

我正在改變一個對象爲getter-setter格式,但是如果引用的方式與我上面展示的方式一樣,這可能會對遺留代碼中的現有引用產生副作用。 – sbr

+0

@sbr啊我明白了。那麼是的,你可能有一個問題,但我恐怕沒有辦法繞過它。雖然有人可能會爭辯說修改setter中的值是不好的做法,因爲調用者並不期望發生這種情況。如果'x> 25'會拋出一個錯誤,以避免手頭的問題,如果你能忍受這種行爲。祝你好運! – Vache

+0

通過一個setter實現它的主要原因是驗證和強制。你能想出一個更好的方法來將驗證器方法附加到每個任務上嗎?像這樣一個簡潔的東西。謝謝 – sbr