18

我已经阅读了很多关于 Javascript 中的闭包的内容这些大括号是干什么用的?我在mozilla.org上读到,它说闭包应该定义为

(function(){...})();

但在http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html上,它说闭包函数是

(function(){...}());

有什么区别或后一个是错误的?最后一个()的目的是什么?你会在里面放一些参数吗?我正在寻找一个很好的参考。

编辑:此外, Mozilla.org上有一个示例

var makeCounter = function() {
var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }  
};

为什么这个“功能”需要分号?如果需要在声明后立即调用,则应在结束分号之前放置 ()。但是没有。

4

4 回答 4

21

The syntax

(function(){...})()

is simply an immediately invoked anonymous function. It does not matter how you use your brackets, as the underlying code is a function being declared, and invoked.

Closures are instead used to describe a situation where a function has access to variables declared outside of its scope, accessible via closures

For clarity :

If we have the following function

   function hello() {
      alert("Hello");
   }

We can call the function with the following

hello()

Which invokes the function 'hello'. But if we do not wish to give it a name, but still invoke it, then we can do

(function hello() {
   alert("Hello");
})()

Which will do the exact same as the previous example of calling hello

However, in this scenario there is no point in giving the function the name 'hello', so we can simply remove it:

(function() {
    alert("Hello");
})()

Which is the notation used in your original question.

于 2013-04-16T09:06:38.653 回答
8

您的示例显示了立即调用函数表达式或 IIFE。它对口译员说:

  • 这是一个功能
  • 它没有名字
  • 使其远离全局范围,即“窗口”
  • 现在打电话

是的,您可以将参数放在最后一个()内。例如:

(
    function(username){
        alert("Hello " + username);
    }
)("John Smith")

闭包是 javascript 的一个特性,它允许我们实现数据隐藏,这大致相当于 C++ 或 Java 等语言中的私有变量。

function getBmiCalculator(height, weight) {
    // These are private vars
    var height = height;
    var weight = weight;

    function calculateBmi(){
        return weight / (height * height);
    }
    return calculateBmi;
}

var calc = getBmiCalculator(1.85, 90);

// calc still has access to the scope where height and weight live.
var bmi = calc();
alert(bmi);

在这个例子中,在 calc 被销毁之前,身高和体重不能被垃圾收集。存在身高和体重的记忆部分或“范围”是“封闭的”

于 2013-04-16T09:49:29.550 回答
3

没有区别。你也可以这样做:

true && function(){ /* code */ }();
0,function(){ /* code */ }();

!function(){ /* code */ }(); // Facebook style
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

// with new    
new function(){ /* code */ }
new function(){ /* code */ }() // if you need arguments then use brackets
于 2013-04-16T09:14:28.197 回答
1

分组运算符可以将函数描述括在没有调用括号的情况下,也可以包括调用括号。即下面的两个表达式都是正确的 FE:

      (function () {})();
      (function () {}());

函数表达式

于 2017-11-09T23:49:50.213 回答