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 FunctionDeclaration
terlihat seperti ini:
function Identifier ( FormalParameterListopt ) { FunctionBody }
Dan FunctionExpression
s:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
Karena Anda dapat melihat token Identifier
(Identifier opt ) FunctionExpression
opsional, 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 FunctionDeclaration
atau 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, FunctionDeclaration
s sebenarnya hanya dapat muncul dalam apa yang disebut " Program
" kode, artinya kode di luar dalam lingkup global, dan di dalam FunctionBody
fungsi-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 Block
hanya 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 FunctionDeclaration
s. 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;
};