2013-04-16 68 views
15

我已閱讀了很多關於Javascript中的閉包的內容 這些括號是什麼? 我對mozilla.org讀它說閉合應該被定義爲Javascript匿名關閉

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

http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html,它說的閉合功能是

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

有什麼區別或後者是錯誤的? last()的用途是什麼?你會在裏面放些參數嗎? 我在尋找一個很好的參考。

編輯: 此外,對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; 
    } 
    } 
}; 

爲什麼需要這個 '功能' 分號的例子嗎?如果需要在聲明後立即調用,則應在結尾分號前加上()。但沒有。

+0

它不是一個封閉,它是一個匿名函數。 – zerkms

+1

[這些自我執行的匿名函數(又名IIFE)實現之間的區別是什麼](http://stackoverflow.com/questions/16026909/what-is-the-difference-between-those-self-executing -anonymous-function-aka-iife) – zerkms

+1

[(...())與(...)()在javascript中的重複](http://stackoverflow.com/questions/8774425/vs-in -javascript-closures) – Quentin

回答

17

語法

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

只是一個立即調用匿名函數。不管你如何使用括號,底層代碼都是被聲明和調用的函數。

閉包的,而不是用來描述這樣一種情況:函數可以訪問它的範圍之外聲明的變量,通過關閉

爲清楚起見訪問:

如果我們有以下功能

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

我們可以調用以下函數

hello() 

它調用函數'hello'。但是,如果我們不希望給它一個名稱,但仍然調用它,那麼我們可以做

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

這將做同樣的呼籲hello

然而前面的例子,在這種情況下有在給該函數的名字沒有一點「你好」,所以我們可以簡單地將其刪除:

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

這是你原來的問題使用的符號。

+0

我相信 - 我在說這兩種調用函數表達式的方法都是一樣的。而且這些閉包與立即調用函數表達式不同。讓我知道如果我誤解了這個問題:) – AlanFoster

+0

是否有關於調用括號的任何好文檔? –

+0

@ user1978421我已經爲你添加了一個漸進的例子 – AlanFoster

2

沒有區別。您也可以這樣做:

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 
+2

爲什麼?這一切都是正確的,但我懷疑JavaScript初學者會理解這些工作的原因。 –

+0

因爲在某些情況下可以保存1個字符:) – Ildar

+2

這不是我的意思。例如。爲什麼'function(){/ * code * /}());'或'+ function(){/ * code * /}();''while function(){/ * code * /}( );'或'* function(){/ * code * /}();'不?這些行允許函數調用的特徵是什麼? –

7

您的示例顯示了Immediately Invoked Function Expression或IIFE。它說的解釋:

  • 這裏是一個功能
  • 它沒有名字
  • 從全球範圍內保持它拿走即「窗口」
  • 現在

叫它是,你可以把參數放在last()中。例如:

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

Closures是JavaScript的一個功能,它允許我們實現data hiding這大致相當於私有變量如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); 

在該示例中,高度&重量不能被垃圾收集,直到計算值被破壞。內存段或「範圍」,其中存在的權重高度爲「關閉」

0

分組操作符可以在沒有調用括號的情況下圍繞函數描述,並且還包括調用括號。即下面兩個表達式都是正確的FE:

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

Function Expression