Nie działa, ponieważ jest analizowany jako a FunctionDeclaration, a identyfikator nazwy deklaracji funkcji jest obowiązkowy .
Gdy otaczasz go nawiasami, jest on oceniany jako a FunctionExpression, a wyrażenia funkcyjne można nazwać lub nie.
Gramatyka FunctionDeclarationwygląda następująco:
function Identifier ( FormalParameterListopt ) { FunctionBody }
I FunctionExpressions:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
Jak widać token Identifier(Identyfikator opt ) FunctionExpressionjest opcjonalny, dlatego możemy mieć wyrażenie funkcyjne bez zdefiniowanej nazwy:
(function () {
alert(2 + 2);
}());
Lub nazwane wyrażenie funkcji:
(function foo() {
alert(2 + 2);
}());
Nawiasy (formalnie nazywane operatorem grupowania ) mogą otaczać tylko wyrażenia, a wyrażenie funkcji jest oceniane.
Dwie produkcje gramatyczne mogą być niejednoznaczne i mogą wyglądać dokładnie tak samo, na przykład:
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
Analizator składni wie, czy jest to a FunctionDeclarationlub a FunctionExpression, w zależności od kontekstu, w którym się pojawia.
W powyższym przykładzie drugi jest wyrażeniem, ponieważ operator przecinka może również obsługiwać tylko wyrażenia.
Z drugiej strony, FunctionDeclarationmogą faktycznie występować tylko w tak zwanym Programkodzie, co oznacza kod poza zakresem globalnym i wewnątrz FunctionBodyinnych funkcji.
Należy unikać funkcji wewnątrz bloków, ponieważ mogą one prowadzić do nieprzewidzianych zachowań, np .:
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
Powyższy kod powinien faktycznie wygenerować SyntaxError , ponieważ a Blockmoże zawierać tylko instrukcje (a Specyfikacja ECMAScript nie definiuje żadnej instrukcji funkcji), ale większość implementacji jest tolerancyjna i po prostu przyjmuje drugą funkcję, tę, która zaalarmuje 'false!'.
Implementacje Mozilli - Rhino, SpiderMonkey - mają inne zachowanie. Ich gramatyka zawiera niestandardowe instrukcję funkcji, co oznacza, że funkcja będzie oceniana w czasie wykonywania , a nie w czasie analizy, jak to ma miejsce w przypadku FunctionDeclarations. W tych implementacjach zdefiniujemy pierwszą funkcję.
Funkcje można zadeklarować na różne sposoby, porównaj następujące :
1- Funkcja zdefiniowana za pomocą konstruktora funkcji przypisanego do zmiennej zwielokrotnia :
var multiply = new Function("x", "y", "return x * y;");
2- Deklaracja funkcji o nazwie mnożącej się :
function multiply(x, y) {
return x * y;
}
3- Wyrażenie funkcyjne przypisane do zmiennej zwielokrotnia się :
var multiply = function (x, y) {
return x * y;
};
4- Nazwane wyrażenie funkcyjne func_name , przypisane do zmiennej pomnóż :
var multiply = function func_name(x, y) {
return x * y;
};