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