【问题标题】:Javascript setter returns value without validationJavascript setter 未经验证返回值
【发布时间】:2014-01-23 01:42:44
【问题描述】:

JavaScript setter 更新引用处的内部值,但返回值不正确。

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 代码按预期执行,可维护性!

【问题讨论】:

  • @FelixKling 预计 updatedPoints 的值为 25 ?
  • 是的,我现在明白你的问题了。但是不,赋值表达式的结果是被赋值的值(即 60)。
  • 我会使用逗号运算符 - 它更短:P var updatedPoints = ( (Game.points = 60), Game.points );

标签: javascript getter-setter javascript-objects ecmascript-5 javascript-engine


【解决方案1】:

JavaScript 简单赋值 (=) 根据规范 (11.13.1) 返回正确的值。此行为会忽略您的 setter 中发生的任何验证。

来自规范:

产生 AssignmentExpression : LeftHandSideExpression = AssignmentExpression 评估如下:

  1. lref 为评估 LeftHandSideExpression 的结果。
  2. rref 为评估 AssignmentExpression 的结果。
  3. rval 为 GetValue(rref)。
  4. 如果以下条件都为真,则抛出 SyntaxError 异常:
    • Type(lref) is Reference is true
    • IsStrictReference(lref) 为 true
    • Type(GetBase(lref)) 是环境记录
    • GetReferencedName(lref) 是“eval”或“arguments
  5. 调用 PutValue(lref, rval)。
  6. 返回rval

因此,按照设计,无法“解决”您的问题。检查Game.points 就足够了。

【讨论】:

  • 我正在将一个对象更改为 getter-setter 格式,但是如果像我上面显示的那样进行引用,这可能会对遗留代码中的现有引用产生副作用。
  • @sbr 啊,我明白了。那么是的,你可能有问题,但恐怕没有办法解决它。尽管有人可能会争辩说,修改 setter 中的值是一种不好的做法,因为调用者并不希望发生这种情况。如果x > 25 抛出错误将避免手头的问题,如果您可以忍受这种行为。祝你好运!
  • 通过setter实现它的主要原因是验证和强制。你能想出一个更好的方法来为每个作业附加一个验证器方法吗?像这样简洁的东西。谢谢
  • 通常验证不会修改输入,它会检查它是否有效,如果不是,则以某种方式阻止输入。这就是为什么我建议抛出异常而不是修改值。除此之外我不知道。如果不真正深入您的项目,很难说出什么对您有意义......
猜你喜欢
  • 2017-04-24
  • 1970-01-01
  • 2014-09-01
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 2018-01-05
  • 2020-03-15
  • 1970-01-01
相关资源
最近更新 更多