2013-04-16 26 views
15

Przeczytałem dużo o zamknięciach w JavaScript Co to są szelki dla? czytałem na mozilla.org który mówi zamknięcie powinno być zdefiniowane jakoJavascript Zamknięcie anonimowe

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

ale na http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html, to mówi, że funkcja zamknięcia jest

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

Co za różnica czy ten ostatni jest nie tak? jaki jest cel ostatniego()? Czy wstawiłbyś jakieś parametry? Szukam dobrego odniesienia.

Edit: Ponadto, jest przykładem na 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; 
    } 
    } 
}; 

dlaczego średnik jest potrzebny do tego 'funkcja'? Jeśli trzeba go wywołać natychmiast po deklaracji, a() należy umieścić przed średnikiem końcowym. Ale nie ma.

+0

to nie jest zamknięcie, to funkcja anonimowa. – zerkms

+1

Dokładny duplikat [Jaka jest różnica między wykonywaniem anonimowej funkcji (zwanej też IIFE)] (http://stackoverflow.com/questions/16026909/what-is-the-difference-between-thoseself- exececuting -anonymous-function-aka-iife) – zerkms

+1

możliwy duplikat [(...()) vs. (...)() w javascript closures] (http://stackoverflow.com/questions/8774425/vs-in -javascript-closures) – Quentin

Odpowiedz

17

Składnia

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

jest po prostu natychmiast wywoływana funkcja anonimowa. Nie ma znaczenia, w jaki sposób używasz nawiasów, ponieważ kod źródłowy jest zadeklarowaną funkcją i wywoływany.

Zamknięcia zamiast tego są używane do opisania sytuacji, w której funkcja ma dostęp do zmiennych zadeklarowanych poza jego zakres, dostępną poprzez zamknięć

Dla jasności:

Jeśli mamy następującą funkcję

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

Możemy nazwać funkcję z następującym

hello() 

Który wywołuje funkcję "cześć". Ale jeśli nie chcemy, aby nadać mu nazwę, ale nadal powoływać się, a potem możemy zrobić

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

Który zrobi dokładnie to samo jak w poprzednim przykładzie wywołanie hello

Jednak w tym scenariuszu nie ma sensu dając funkcja nazwę „cześć”, więc może po prostu usunąć go:

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

który jest notacja stosowana w oryginalnym pytanie.

+0

Tak wierzę - mówię, że obie metody wywoływania funkcji są takie same. A te zamknięcia różnią się od natychmiast przywoływanych wyrażeń funkcyjnych. Daj mi znać, jeśli źle zinterpretowałem pytanie :) – AlanFoster

+0

Czy istnieje dobra dokumentacja dotycząca nawiasów wywołania? –

+0

@ user1978421 Dodałem stopniowy przykład tego dla ciebie – AlanFoster

2

Nie ma różnicy. Można również zrobić tak:

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

I dlaczego tak jest? To wszystko jest poprawne, ale wątpię, aby początkujący JavaScript zrozumiał, dlaczego to działa. –

+0

Ponieważ w niektórych przypadkach można zapisać 1 znak :) – Ildar

+2

Nie o to mi chodziło. Na przykład. dlaczego '(function() {/ * code * /}());' lub '+ function() {/ * code * /}();' work while' function() {/ * code * /} (); 'lub' * function() {/ * code * /}(); 'nie? Jakie są cechy tych linii, które umożliwiają wywoływanie funkcji? –

7

Twój przykład pokazuje Immediately Invoked Function Expression lub Iife.Mówi do tłumacza:

  • tutaj jest funkcją
  • to nie ma nazwy
  • trzymać go z dala od zasięgu globalnym tj „window”
  • nazywamy go teraz

Tak , możesz umieścić parametry wewnątrz ostatniego(). Na przykład:

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

Closures są cechą JavaScript, który pozwala nam na realizację data hiding który jest mniej więcej odpowiednikiem zmiennych prywatnych w językach takich jak C++ lub 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); 

W tym przykładzie, wysokość & ciężar nie może być porządkowania pamięci, dopóki obliczona zostaje zniszczona. Sekcja pamięci lub "zakresu", w którym istnieje masa o wysokości &, to "Zamknięta"

0

operator grupujący może otaczać opis funkcji jako bez nawiasów połączeń, a także w nawiasach połączeń. To znaczy. Poniższe oba wyrażenia są poprawne FE:

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

Function Expression