function

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

function 宣告建立一個新函式的繫結,並賦予其給定名稱。

你也可以使用function 表示式來定義函式。

試一試

function calcRectArea(width, height) {
  return width * height;
}

console.log(calcRectArea(5, 6));
// Expected output: 30

語法

js
function name(param0) {
  statements
}
function name(param0, param1) {
  statements
}
function name(param0, param1, /* …, */ paramN) {
  statements
}

引數

name

函式名稱。

param 可選

函式的形參名稱。不同引擎中引數的最大數量各不相同。有關引數的語法,請參閱函式參考

statements 可選

構成函式體的語句。

描述

一個 function 宣告會建立一個 Function 物件。每次呼叫函式時,它會返回由最後執行的 return 語句指定的值,或者如果到達函式體的末尾則返回 undefined。有關函式的詳細資訊,請參閱函式

function 宣告的行為類似於 varlet 的混合體

  • let 類似,在嚴格模式下,函式宣告的作用域限定在最近的包含塊內
  • let 類似,模組頂層或嚴格模式下塊內的函式宣告不能被任何其他宣告重新宣告
  • var 類似,指令碼頂層(嚴格或非嚴格)的函式宣告會成為 globalThis 的屬性。指令碼或函式體頂層(嚴格或非嚴格)的函式宣告可以被另一個 functionvar 重新宣告。
  • 與兩者都類似,函式宣告可以被重新賦值,但應避免這樣做。
  • 與兩者都不同,函式宣告與它的值一起被提升,並且可以在其作用域內的任何地方呼叫。

塊級函式宣告

警告:非嚴格模式下,塊內的函式宣告行為異常。只有在嚴格模式下才在塊內宣告函式。

函式可以有條件地宣告——也就是說,函式語句可以巢狀在 if 語句中。然而,在非嚴格模式下,不同實現的結果不一致。

js
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

無論 if 主體是否實際執行,作用域和提升效果都不會改變。

js
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

嚴格模式下,塊級函式宣告的作用域限定在該塊內,並被提升到塊的頂部。

js
"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

提升

JavaScript 中的函式宣告被提升到其包含函式或全域性作用域的頂部。你可以在宣告函式之前使用它

js
hoisted(); // Logs "foo"

function hoisted() {
  console.log("foo");
}

請注意,函式表示式不會被提升

js
notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function () {
  console.log("bar");
};

重新宣告

function 宣告是否可以在同一作用域中被重新宣告,取決於它所包含的作用域。

在指令碼的頂層,function 宣告的行為類似於 var,並且可以被另一個 functionvar 重新宣告,但不能被 letconstclass 重新宣告。

js
function a(b) {}
function a(b, c) {}
console.log(a.length); // 2
let a = 2; // SyntaxError: Identifier 'a' has already been declared

function 宣告被 var 重新宣告時,無論它們的相對位置如何,var 宣告的初始化器總是覆蓋函式的值。這是因為函式宣告在任何初始化器被評估之前就被提升,所以初始化器在後面,並覆蓋了值。

js
var a = 1;
function a() {}
console.log(a); // 1

在函式體的頂層,function 也表現得像 var,可以被重新宣告或與引數同名。

js
function foo(a) {
  function a() {}
  console.log(typeof a);
}

foo(2); // Logs "function"

在模組的頂層或嚴格模式下的塊內,function 宣告的行為類似於 let,不能被任何其他宣告重新宣告。

js
// Assuming current source is a module
function foo() {}
function foo() {} // SyntaxError: Identifier 'foo' has already been declared
js
"use strict";
{
  function foo() {}
  function foo() {} // SyntaxError: Identifier 'foo' has already been declared
}

catch 塊內的 function 宣告不能與 catch 繫結的識別符號同名,即使在非嚴格模式下也是如此。

js
try {
} catch (e) {
  function e() {} // SyntaxError: Identifier 'e' has already been declared
}

示例

使用函式

以下程式碼聲明瞭一個函式,當給定三種產品的銷售數量時,它返回總銷售額。

js
function calcSales(unitsA, unitsB, unitsC) {
  return unitsA * 79 + unitsB * 129 + unitsC * 699;
}

規範

規範
ECMAScript® 2026 語言規範
# sec-function-definitions

瀏覽器相容性

另見