Nó không hoạt động vì nó được phân tích cú pháp dưới dạng FunctionDeclaration
và định danh tên của khai báo hàm là bắt buộc .
Khi bạn bao quanh nó bằng dấu ngoặc đơn, nó được đánh giá là a FunctionExpression
và các biểu thức hàm có thể được đặt tên hoặc không.
Ngữ pháp của một FunctionDeclaration
hình như thế này:
function Identifier ( FormalParameterListopt ) { FunctionBody }
Và FunctionExpression
s:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
Như bạn có thể thấy mã thông báo Identifier
(Định danh opt ) trong FunctionExpression
là tùy chọn, do đó chúng ta có thể có biểu thức hàm mà không có tên được xác định:
(function () {
alert(2 + 2);
}());
Hoặc biểu thức hàm được đặt tên :
(function foo() {
alert(2 + 2);
}());
Dấu ngoặc đơn (chính thức được gọi là Toán tử nhóm ) chỉ có thể bao quanh các biểu thức và một biểu thức hàm được ước tính.
Hai sản phẩm ngữ pháp có thể mơ hồ và chúng có thể trông giống hệt nhau, ví dụ:
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
Trình phân tích cú pháp biết đó là a FunctionDeclaration
hay a FunctionExpression
, tùy thuộc vào ngữ cảnh nơi nó xuất hiện.
Trong ví dụ trên, cái thứ hai là một biểu thức vì toán tử Comma cũng chỉ có thể xử lý các biểu thức.
Mặt khác, FunctionDeclaration
s thực sự chỉ có thể xuất hiện trong Program
mã được gọi là " ", nghĩa là mã bên ngoài trong phạm vi toàn cầu và bên trong FunctionBody
các chức năng khác.
Nên tránh các chức năng bên trong các khối, bởi vì chúng có thể dẫn đến một hành vi không thể đoán trước, ví dụ:
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
Đoạn mã trên thực sự sẽ tạo ra một SyntaxError
, vì Block
chỉ có thể chứa các câu lệnh (và Đặc tả ECMAScript không định nghĩa bất kỳ câu lệnh hàm nào), nhưng hầu hết các triển khai đều có thể chấp nhận được và chỉ đơn giản là sẽ lấy hàm thứ hai, một cảnh báo 'false!'
.
Việc triển khai Mozilla -Rhino, SpiderMonkey, - có một hành vi khác. Ngữ pháp của họ chứa Tuyên bố hàm không chuẩn , nghĩa là hàm sẽ được đánh giá trong thời gian chạy , không phải lúc phân tích cú pháp, như xảy ra với FunctionDeclaration
s. Trong những triển khai đó, chúng ta sẽ có được hàm đầu tiên được xác định.
Các hàm có thể được khai báo theo nhiều cách khác nhau, so sánh như sau :
1- Một hàm được xác định với hàm tạo Hàm được gán cho biến nhân :
var multiply = new Function("x", "y", "return x * y;");
2- Một khai báo hàm của một hàm có tên là bội :
function multiply(x, y) {
return x * y;
}
3- Một biểu thức hàm được gán cho biến nhân :
var multiply = function (x, y) {
return x * y;
};
4- Một biểu thức hàm có tên func_name , được gán cho biến nhân :
var multiply = function func_name(x, y) {
return x * y;
};