function
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Khai báo function tạo một binding của hàm mới với tên đã cho.
Bạn cũng có thể định nghĩa hàm bằng cách sử dụng biểu thức function.
Try it
function calcRectArea(width, height) {
return width * height;
}
console.log(calcRectArea(5, 6));
// Expected output: 30
Cú pháp
function name(param0) {
statements
}
function name(param0, param1) {
statements
}
function name(param0, param1, /* …, */ paramN) {
statements
}
Tham số
name-
Tên hàm.
paramOptional-
Tên tham số hình thức của hàm. Số lượng tham số tối đa khác nhau tùy theo từng engine. Về cú pháp tham số, xem tham chiếu Functions.
statementsOptional-
Các câu lệnh tạo nên thân hàm.
Mô tả
Khai báo function tạo ra một đối tượng Function. Mỗi lần hàm được gọi, nó trả về giá trị được chỉ định bởi câu lệnh return cuối cùng được thực thi, hoặc undefined nếu đến cuối thân hàm mà không có câu lệnh return. Xem functions để biết thêm thông tin chi tiết về hàm.
Khai báo function hoạt động như sự kết hợp giữa var và let:
- Giống như
let, trong chế độ strict, khai báo hàm có phạm vi là block gần nhất chứa nó. - Giống như
let, khai báo hàm ở cấp cao nhất của một module hoặc bên trong các block trong chế độ strict không thể bị khai báo lại bởi bất kỳ khai báo nào khác. - Giống như
var, khai báo hàm ở cấp cao nhất của một script (strict hay không strict) trở thành thuộc tính củaglobalThis. Khai báo hàm ở cấp cao nhất của script hoặc thân hàm (strict hay không strict) có thể bị khai báo lại bởi mộtfunctionhoặcvarkhác. - Giống cả hai, khai báo hàm có thể được gán lại, nhưng bạn nên tránh làm vậy.
- Khác với cả hai, khai báo hàm được hoisted cùng với giá trị của nó và có thể được gọi ở bất kỳ đâu trong phạm vi của nó.
Khai báo hàm ở cấp block
Warning: Trong chế độ không strict, khai báo hàm bên trong các block hoạt động một cách kỳ lạ. Chỉ khai báo hàm trong các block khi bạn đang ở chế độ strict.
Hàm có thể được khai báo có điều kiện — nghĩa là, một câu lệnh hàm có thể được lồng bên trong một câu lệnh if. Tuy nhiên, trong chế độ không strict, kết quả không nhất quán giữa các implementation.
console.log(
`'foo' name ${
"foo" in globalThis ? "is" : "is not"
} global. typeof foo is ${typeof foo}`,
);
if (false) {
function foo() {
return 1;
}
}
// In Chrome:
// 'foo' name is global. typeof foo is undefined
//
// In Firefox:
// 'foo' name is global. typeof foo is undefined
//
// In Safari:
// 'foo' name is global. typeof foo is function
Hiệu ứng phạm vi và hoisting sẽ không thay đổi bất kể thân if có thực sự được thực thi hay không.
console.log(
`'foo' name ${
"foo" in globalThis ? "is" : "is not"
} global. typeof foo is ${typeof foo}`,
);
if (true) {
function foo() {
return 1;
}
}
// In Chrome:
// 'foo' name is global. typeof foo is undefined
//
// In Firefox:
// 'foo' name is global. typeof foo is undefined
//
// In Safari:
// 'foo' name is global. typeof foo is function
Trong chế độ strict, khai báo hàm ở cấp block có phạm vi trong block đó và được hoisted lên đầu block.
"use strict";
{
foo(); // Logs "foo"
function foo() {
console.log("foo");
}
}
console.log(
`'foo' name ${
"foo" in globalThis ? "is" : "is not"
} global. typeof foo is ${typeof foo}`,
);
// 'foo' name is not global. typeof foo is undefined
Hoisting
Khai báo hàm trong JavaScript được hoisted lên đầu hàm bao ngoài hoặc phạm vi toàn cục. Bạn có thể sử dụng hàm trước khi khai báo nó:
hoisted(); // Logs "foo"
function hoisted() {
console.log("foo");
}
Lưu ý rằng biểu thức hàm không được hoisted:
notHoisted(); // TypeError: notHoisted is not a function
var notHoisted = function () {
console.log("bar");
};
Khai báo lại
Việc khai báo function có thể được khai báo lại trong cùng phạm vi hay không phụ thuộc vào phạm vi mà nó nằm trong.
Ở cấp cao nhất của script, khai báo function hoạt động như var và có thể được khai báo lại bởi một function hoặc var khác nhưng không thể bởi let, const, hay class.
function a(b) {}
function a(b, c) {}
console.log(a.length); // 2
let a = 2; // SyntaxError: Identifier 'a' has already been declared
Khi khai báo function bị khai báo lại bởi var, bộ khởi tạo của khai báo var luôn ghi đè giá trị của hàm, bất kể thứ tự tương đối của chúng. Điều này là do khai báo hàm được hoisted trước khi bất kỳ bộ khởi tạo nào được đánh giá, vì vậy bộ khởi tạo đến sau và ghi đè giá trị.
var a = 1;
function a() {}
console.log(a); // 1
Ở cấp cao nhất của thân hàm, function cũng hoạt động như var và có thể được khai báo lại hoặc có cùng tên với một tham số.
function foo(a) {
function a() {}
console.log(typeof a);
}
foo(2); // Logs "function"
Ở cấp cao nhất của một module hoặc một block trong chế độ strict, khai báo function hoạt động như let và không thể được khai báo lại bởi bất kỳ khai báo nào khác.
// Assuming current source is a module
function foo() {}
function foo() {} // SyntaxError: Identifier 'foo' has already been declared
"use strict";
{
function foo() {}
function foo() {} // SyntaxError: Identifier 'foo' has already been declared
}
Khai báo function bên trong một block catch không thể có cùng tên với định danh bị ràng buộc bởi catch, kể cả trong chế độ không strict.
try {
} catch (e) {
function e() {} // SyntaxError: Identifier 'e' has already been declared
}
Ví dụ
>Sử dụng function
Đoạn code sau khai báo một hàm trả về tổng doanh số bán hàng, khi được cung cấp số lượng đơn vị đã bán của ba sản phẩm.
function calcSales(unitsA, unitsB, unitsC) {
return unitsA * 79 + unitsB * 129 + unitsC * 699;
}
Thông số kỹ thuật
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-function-definitions> |