【问题标题】:Object defineProperty confuses the way I think about hoisting / sync and async js [duplicate]对象defineProperty混淆了我对提升/同步和异步js的看法[重复]
【发布时间】:2026-01-14 00:05:01
【问题描述】:

当谈到浏览器如何加载数据并将其呈现给用户时,我认为我对异步/同步/提升有很好的理解。然而,下面这个例子让我陷入了一个循环,让我发布这个例子然后解释这个问题:

var obj = {
  counter: 0,
};

Object.defineProperty(obj, 'reset', {
  get: function() {
    return this.counter = 2;
  }
});

Object.defineProperty(obj, "increment", {
  get: function() {
    return this.counter++;
  }
});

Object.defineProperty(obj, "decrement", {
  get: function() {
    return this.counter--;
  }
});

console.log(obj.reset) //2
console.log(obj.increment + ' ' + "incremented") // "2 incremented"
console.log(obj.decrement + ' ' + "decremented") // "3 decremented"

认为浏览器解释这个的方式是同步运行应该产生的每一行代码:

//2
//2 incremented
//2 decremented

因为如果您在调用控制台日志之前一直跟踪对“计数器”的更改,计数器将从 0 变为 2 再到 3 再变为 2。

然后我等一下;如果返回的值不全是 2,那么调用这些控制台日志可能是一种获取数据的异步方式,这在逻辑上会让我认为结果应该是:

//2
//3
//2

因为如果您在运行控制台日志时访问“计数器”属性的位置,那么从逻辑上讲,计数器值会在 (obj.reset) 时从 0 变为 2 然后 3 on(obj.increment) 然后 2 on(obj.decrement)

我对浏览器如何解释这一点的方式显然是错误的,并且希望清楚地逐步解释为什么返回的值是:

//2
//2 incremented
//3 decremented

如果可能的话,谢谢。

【问题讨论】:

  • 这与异步或提升无关,只是后增量和后减运算符的工作方式。

标签: javascript increment getter-setter


【解决方案1】:

这与异步无关。 console.log 正在接收一个表达式并打印该值。 obj.increment 返回 2 因为这就是 postfix ++ 运算符的工作方式。它增加数字并在增加之前返回值。所以,它最终是

console.log(2 + ' ' + "incremented") 

console.log() 方法最终得到字符串 2 incremented。同样的逻辑适用于decrement。表达式变为console.log(3 + ' ' + "decremented")

【讨论】:

    【解决方案2】:

    你注意到了吗?

    var cpt_A = 5;
    var cpt_B = 5;
    
    function func_A(){ return cpt_A-- } 
    function func_B(){ return --cpt_B } 
    
    console.log ( func_A() )   //  return 5.
    console.log ( func_B() )   //  return 4.

    它是C语言编程的基础。在func_A的情况下,它返回cpt_A的值,然后进行递减操作。在 func_B 的情况下,它对 cpt_B 进行递减操作,然后返回结果。

    【讨论】:

    • 减量运算符不应该像cpt_B那样在cpt_B之后吗? func_A 不应该返回 4 吗?
    • 不,这是两个不同的动作顺序。这是一个经典案例。