使用闭包时出现以下 JavaScript 语法的原因是什么?

What's the reason of the following JavaScript syntax when using closures?

研究闭包,我查看了有关它的开发人员的 Mozilla 文章,并看到了以下代码:

var counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }

  return {
    increment: function() {
      changeBy(1);
    },

    decrement: function() {
      changeBy(-1);
    },

    value: function() {
      return privateCounter;
    }
  };
})();

console.log(counter.value());  // 0.

counter.increment();
counter.increment();
console.log(counter.value());  // 2.

counter.decrement();
console.log(counter.value());  // 1.

我对函数如何归因于变量感到困惑counter,因为函数最初是被那些括号包围的,毕竟还有两个不可分解的括号在一起...我只是想知道,这种语法的原因是什么?我当然会做:

var counter = function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }

  return {
    increment: function() {
      changeBy(1);
    },

    decrement: function() {
      changeBy(-1);
    },

    value: function() {
      return privateCounter;
    }
  };
};

但是我得到了错误

Uncaught TypeError: counter.value is not a function

当我做的时候console.log(counter.value());

谁能给我解释一下吗?

您看到的是立即调用的函数表达式或 IIFE。此代码正在创建一个函数,然后立即调用该函数,然后将函数的 return 值 分配给 counter。所以 counter 不是一个函数,它是一个具有三个属性的对象:incrementdecrementvalue.

他们使用 IIFE 的原因是为了使本质上成为私有变量。 privateCounter 仅在该函数内的其他代码的范围内,这意味着只有 incrementdecrementvalue 可以访问它。

如果他们不关心将变量设为私有,则等效代码为:

var publicCounter = 0;
function changeBy(val) {
  publicCounter += val;
}

var counter = {
  increment: function() {
    changeBy(1);
  },
  decrement: function() {
    changeBy(-1);
  },
  value: function() {
    return publicCounter;
  }
}