Ini tidak berfungsi karena sedang diuraikan sebagai FunctionDeclaration, dan pengidentifikasi nama deklarasi fungsi adalah wajib .
Ketika Anda mengelilinginya dengan tanda kurung itu dievaluasi sebagai FunctionExpression, dan ekspresi fungsi dapat dinamai atau tidak.
Tata bahasanya FunctionDeclarationterlihat seperti ini:
function Identifier ( FormalParameterListopt ) { FunctionBody }
Dan FunctionExpressions:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
Karena Anda dapat melihat token Identifier(Identifier opt ) FunctionExpressionopsional, oleh karena itu kami dapat memiliki ekspresi fungsi tanpa nama yang ditentukan:
(function () {
alert(2 + 2);
}());
Atau yang bernama ekspresi fungsi:
(function foo() {
alert(2 + 2);
}());
Tanda kurung (secara resmi disebut Pengelompokan Operator ) hanya dapat mengelilingi ekspresi, dan ekspresi fungsi dievaluasi.
Dua produksi tata bahasa bisa ambigu, dan mereka dapat terlihat persis sama, misalnya:
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
Parser tahu apakah itu a FunctionDeclarationatau a FunctionExpression, tergantung pada konteks di mana ia muncul.
Dalam contoh di atas, yang kedua adalah ekspresi karena operator Koma juga dapat menangani hanya ekspresi.
Di sisi lain, FunctionDeclarations sebenarnya hanya dapat muncul dalam apa yang disebut " Program" kode, artinya kode di luar dalam lingkup global, dan di dalam FunctionBodyfungsi-fungsi lainnya.
Fungsi di dalam blok harus dihindari, karena dapat menyebabkan perilaku yang tidak terduga, misalnya:
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
Kode di atas seharusnya benar-benar menghasilkan a SyntaxError, karena a Blockhanya dapat berisi pernyataan (dan Spesifikasi Naskah ECMAS tidak mendefinisikan pernyataan fungsi apa pun), tetapi sebagian besar implementasi bersifat toleran, dan hanya akan mengambil fungsi kedua, yang diperingatkan 'false!'.
Implementasi Mozilla -Rhino, SpiderMonkey, - memiliki perilaku yang berbeda. Tata bahasa mereka mengandung Pernyataan Fungsi non-standar , yang berarti bahwa fungsi tersebut akan dievaluasi pada saat run-time , bukan pada waktu parse, seperti yang terjadi pada FunctionDeclarations. Dalam implementasi tersebut kita akan mendefinisikan fungsi pertama.
Fungsi dapat dideklarasikan dengan cara yang berbeda, bandingkan yang berikut :
1- Fungsi yang didefinisikan dengan konstruktor Fungsi yang ditugaskan ke variabel multiply :
var multiply = new Function("x", "y", "return x * y;");
2- Deklarasi fungsi dari suatu fungsi bernama multiply :
function multiply(x, y) {
return x * y;
}
3- Ekspresi fungsi yang ditugaskan ke variabel multiply :
var multiply = function (x, y) {
return x * y;
};
4- Nama fungsi func_name ekspresi , ditugaskan untuk variabel multiply :
var multiply = function func_name(x, y) {
return x * y;
};