function

function 声明创建一个给定名称的新函数的 binding

¥The function declaration creates a binding of a new function to a given name.

你还可以使用 function 表达

¥You can also define functions using the function expression.

Try it

语法

¥Syntax

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

参数

¥Parameters

name

函数名称。

param Optional

函数的形式参数的名称。不同引擎中的最大参数数有所不同。有关参数的语法,请参阅 函数参考

statements Optional

构成函数体的语句。

描述

¥Description

function 声明创建 Function 对象。每次调用函数时,它返回最后执行的 return 语句指定的值,如果到达函数体末尾,则返回 undefined。有关功能的详细信息,请参阅 functions

¥A function declaration creates a Function object. Each time when a function is called, it returns the value specified by the last executed return statement, or undefined if the end of the function body is reached. See functions for detailed information on functions.

function 声明的行为类似于 varlet 的混合:

¥function declarations behave like a mix of var and let:

  • let 一样,在严格模式下,函数声明的作用域为最接近的包含块
  • let 一样,严格模式下模块顶层或块内的函数声明不能被任何其他声明视为 redeclared
  • var 一样,脚本顶层的函数声明(严格或非严格)成为 globalThis 上的属性。脚本或函数体顶层的函数声明(严格或非严格)可以由另一个 functionvar 重新声明。
  • 与两者一样,函数声明可以重新分配,但你应该避免这样做。
  • 与两者不同的是,函数声明是 hoisted 及其值,并且可以在其范围内的任何位置调用。

块级函数声明

¥Block-level function declaration

警告:在 非严格模式 中,块内的函数声明行为很奇怪。如果处于严格模式,则仅在块中声明函数。

¥Warning: In non-strict mode, function declarations inside blocks behave strangely. Only declare functions in blocks if you are in strict mode.

函数可以有条件地声明 - 也就是说,函数语句可以嵌套在 if 语句中。然而,在非严格模式下,不同实现的结果不一致。

¥Functions can be conditionally declared — that is, a function statement can be nested within an if statement. However, in non-strict mode, the results are inconsistent across implementations.

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 主体是否实际执行,作用域和提升效果都不会改变。

¥The scoping and hoisting effect won't change regardless of whether the if body is actually executed.

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

严格模式 中,block 级函数声明的作用域为该块,并提升到块的顶部。

¥In strict mode, block-level function declarations are scoped to that block and are hoisted to the top of the block.

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

提升

¥Hoisting

JavaScript 中的函数声明是 hoisted 到封闭函数或全局范围的顶部。你可以在声明之前使用该函数:

¥Function declarations in JavaScript are hoisted to the top of the enclosing function or global scope. You can use the function before you declared it:

js
hoisted(); // Logs "foo"

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

请注意,函数表达式 未提升:

¥Note that function expressions are not hoisted:

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

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

重新声明

¥Redeclarations

function 声明是否可以在同一作用域中重新声明取决于它包含在哪个作用域中。

¥Whether function declarations can be redeclared in the same scope depends on what scope it's contained in.

在脚本的顶层,function 声明的行为类似于 var,并且可以由另一个 functionvar 重新声明,但不能由 letconstclass 重新声明。

¥At the top level of a script, function declarations behave like var and can be redeclared by another function or var but not by let, const, or class.

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

var 重新声明 function 声明时,var 声明的初始值设定项始终会覆盖函数的值,无论它们的相对位置如何。这是因为函数声明在任何初始值设定项被评估之前被提升,因此初始值设定项稍后出现并覆盖该值。

¥When function declarations are redeclared by var, the var declaration's initializer always overrides the function's value, regardless of their relative position. This is because function declarations are hoisted before any initializer gets evaluated, so the initializer comes later and overrides the value.

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

在函数体的顶层,function 的行为也类似于 var,并且可以重新声明或与参数具有相同的名称。

¥At the top level of a function's body, function also behaves like var and can be redeclared or have the same name as a parameter.

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

foo(2); // Logs "function"

在严格模式下模块或块的顶层,function 声明的行为与 let 类似,并且不能由任何其他声明重新声明。

¥At the top level of a module or a block in strict mode, function declarations behave like let and cannot be redeclared by any other declaration.

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 绑定标识符具有相同的名称,即使在非严格模式下也是如此。

¥A function declaration within a catch block cannot have the same name as the catch-bound identifier, even in non-strict mode.

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

示例

¥Examples

使用功能

¥Using function

以下代码声明一个函数,当给定三种产品的销售单位数时,该函数返回销售总额。

¥The following code declares a function that returns the total amount of sales, when given the number of units sold of three products.

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

规范

Specification
ECMAScript Language Specification
# sec-function-definitions

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看