为什么 iife 中 `X` 的值会根据我们访问它的方式而变化?

Why value of `X` in iife chage based on the way we access it?

我有以下js代码。

var a = (function(){
    var x = 0;
    var y = function(){
        x++;
        console.log(x);
    }
    var z = function(){
        return x;
    }
    return {
        x, y, z
    }
})();

在这里,当我第一次尝试访问 a.x 时,它给我输出 0(预计 x 被初始化为 0),然后我递增的值x 使用函数 y。但是在 x 的值递增两次(或者可能超过 2 次)之后,当我尝试访问 x 的值时,它仍然给我 a.x=0。我无法理解为什么会这样,因为我已经使用函数 y 更改了 x 的值。那为什么没有变化呢

(但是当我通过某个函数访问 x 的值时,它给出了递增的值。为什么会有这种不同的行为。如果我直接访问同一个变量,那么它会给出一些输出,当我访问相同的变量值时通过某个函数返回它给出了一些其他值。为什么?)

var a = (function(){
  var x = 0;
  var y = function(){
 x++;
 console.log(x);
  }
  var z = function(){
 return x;
  }
  return {
 x, y, z
  }
})();

console.log(a.x);
a.y();
a.y();
console.log(a.x);
console.log(a.z());

猜想是因为关闭但不确定。

当您创建对象并return它时:

return {
  x, y, z
}

对象中的x属性接收局部变量x副本。除此以外,它不以任何方式绑定到局部变量,因此闭包中变量的后续更改不会反映在该对象中。

你可以做一个 getter:

return {
  get x() { return x; },
  y, z
};

这将导致对 returned 对象的 "x" 属性 的任何访问都在闭包中获取 x 的当前值。

最后一行:

   return { x, y, z };

等同于:

  return { x: x, y: y, z: z };

所以它复制局部变量到对象中。对于无关紧要的函数或对象,因为它们是通过引用复制的,而基元是通过值复制的,因此你有两个不同的 z,一个局部变量和一个对象 属性.