javascript return语句在setter中做什么?

aor9mmx1  于 2023-11-15  发布在  Java
关注(0)|答案(4)|浏览(176)

我有以下代码:

  1. var o = {};
  2. o.a = 1;
  3. var _value = 1;
  4. Object.defineProperty(o,"a",{
  5. set: function(value){
  6. _value = value + 1;
  7. console.log("log: ", value, _value);
  8. return _value;
  9. },
  10. get: function(){
  11. return _value;
  12. }
  13. });

字符串
在setter方法中,我在返回_value之前将其递增1。因此,如果我设置o.a = 5,我希望控制台打印6(即使我意识到从setter返回值通常没有意义)。然而,如以下片段所示,控制台打印5

  1. > o.a = 5;
  2. log: 5 6 // from console.log;
  3. 5 // return; why does it == value and not value + 1?
  4. > o.a;
  5. 6
  6. > var i = o.a = 5;
  7. > i;
  8. 5
  9. > o.a;
  10. 6


那么我的问题是为什么它返回5而不是6
我希望这不是因为我在代码中犯了一些愚蠢的错误。

dz6r00yl

dz6r00yl1#

你不能从属性设置器返回任何东西,而只是得到赋值的值(它是5,因为你赋值了5)。
setter中的return是做什么的?
什么都没有。最好删除return语句。最好忽略它。

l2osamch

l2osamch2#

让我们来看看 * 简单的赋值 *:

11.13.1简单赋值(=)

结果 AssignmentExpression:LeftHandSideExpression = AssignmentExpression 的计算如下:
1.令 lref 为计算 LeftHandSideExpression 的结果。
1.令 rref 为计算 AssignmentExpression 的结果。
1.设 rval 为GetValue(rref)。
所以rval被赋给了将要被赋给左手的值(o.a)。在你的例子中是5
1.如果以下条件都为真,则抛出SyntaxError异常:[...]
1.调用PutValue(lrefrval)。
这是将值赋给左手侧(PutValue(o.a, 5))的地方。正如你所看到的,PutValue返回的值没有任何作用(它不返回任何东西)。
1.返回 rval
它简单地返回分配的值,在您的情况下为5
赋值表达式始终返回已赋值的值。

展开查看全部
holgip5t

holgip5t3#

赋值表达式的值总是等于被赋值的值:

  1. var a;
  2. console.log(a = 7); // logs 7

字符串
这是真的,不管你要赋值的对象是变量、普通属性、setter、只读属性还是其他什么:

  1. var a = {};
  2. Object.defineProperty(a, "b", { value: 8, writable: false });
  3. console.log(a.b = 9); // logs 9
  4. console.log(a.b); // logs 8, because a.b is read-only


正如你自己所说的,setter中的返回值是没有意义的,所以当你在setter中使用返回值时,为什么你期望它实际上做一些特殊的事情呢?回答你的问题 “return语句在setter中做什么?" -基本上什么都没有。它计算return右边的表达式,然后丢弃结果。

m528fe3b

m528fe3b4#

这在某种程度上取决于你为什么要这样做。我个人有一组枚举,但其中一个有一个边缘情况,为边缘情况设置一个例外会在我的API中产生不一致。我想我会用一个返回值的setter来伪造它,但正如你所发现的那样,这不起作用。
这个问题的一个潜在的解决方案是使用带代理的getter。* 这意味着你没有像你要求的那样从setter返回 *,但是下面的代码将显示为什么这可能正是你实际需要的。
我遇到的问题是:捕获一个鼠标按钮并返回一个友好的名称。如果它是0-2,则返回以下之一:'MouseClickLeft','MouseClickRight','MouseClickMiddle'。否则,返回一个动态数字,如'MouseClick 4','MouseClick 5'等。使其像枚举一样工作,以保持API与其他枚举一致。

  1. const baseEnums = {
  2. 0: 'MouseClickLeft',
  3. 1: 'MouseClickRight',
  4. 2: 'MouseClickMiddle',
  5. };
  6. const MouseButtonName = new Proxy(baseEnums, {
  7. get: function(target, name) {
  8. return target[name] || `MouseClick${name}`;
  9. }
  10. });

字符串
输出示例:

  1. MouseButtonName['0']; // 'MouseClickLeft'
  2. MouseButtonName['1']; // 'MouseClickRight'
  3. MouseButtonName['2']; // 'MouseClickMiddle'
  4. MouseButtonName['3']; // 'MouseClick3'
  5. MouseButtonName['5']; // 'MouseClick5'


上面我使用了数字转换为字符串,但文本字符串的工作方式相同。

展开查看全部

相关问题