函数

函数是可重复使用的模块化语句块,用于执行一组 相关任务,例如根据参数计算和返回值 提供给函数的参数。与所有非原始值一样, 函数就是对象。它们是独一无二的对象,可以调用它们 需要执行代码、以实参的形式传递数据, 并返回值。

函数被视为“头等” 对象,这意味着尽管它们的行为独特,但可用于所有 与任何其他 JavaScript 对象相同的上下文。例如,函数可以是 赋值给变量,作为参数传递给其他函数,并返回 由其他函数触发。

function myFunction() {
   console.log( "This is my function." );
};

定义为对象属性的函数 通常称为“方法”。与使用 var 声明的变量一样, 在封装函数之外进行的函数声明会添加到 全局对象作为方法。

函数声明

函数声明(也称为“函数语句”或“函数定义”) 会创建一个可在所属作用域中的其他位置调用的命名函数。 函数声明包含 function 关键字,后跟 一个 ID、一个以括号括起来的逗号分隔参数列表,以及一个 block 语句 “function body”您经常会遇到 以英文分号结尾;因为函数声明是一个尾随语句 英文分号可通过 ASI 推断出来。

function myFunction() {
   console.log( "This is my function." );
};

myFunction();
> "This is my function."

由于 JavaScript 早期设计决策的保留,函数声明 都具有相同的旧版提升 行为表现为使用 var 声明的变量,这意味着函数声明 会提升到其作用域顶部,并且可以在声明前作为 结果,无论该范围是否受严格模式约束:

"use strict";
{
    myFunction();
    function myFunction() {
        console.log( "This is my function." );
    };
}
> "This is my function."

严格模式之外,函数 声明使用 JavaScript 的旧版作用域 行为,这意味着函数声明的作用域限定为与其最接近的 函数:

function myFunction() {
    function myNestedFunction() {
        console.log( "This is my nested function." );
    }
    myNestedFunction();
};

myFunction();
> "This is my nested function."

myNestedFunction();
>Uncaught ReferenceError: myNestedFunction is not defined

严格模式下,函数声明 与使用 letconst

"use strict";
{
    function myFunction() {
        console.log( "This is my function." );
    };
}

myFunction();
> Uncaught ReferenceError: myFunction is not defined

调用函数

与变量一样,声明函数时使用的标识符充当 值的符号名称。如果仅通过标识符引用函数会返回 只执行函数对象,不执行其中包含的函数:

function myFunction() {
   console.log( "This is my function." );
};

myFunction;
> myFunction() {
   console.log( "This is my function." );
}

如需在函数正文中执行代码,请调用(或 invoke)函数 在函数名称后面添加一对匹配的括号:

function myFunction() {
    console.log( "My function has been executed." );
}

myFunction();
> "My function has been executed."

函数定义中的形参充当 在调用函数时可以传入函数正文的值。 调用函数时,圆括号中的值称为“实参”(尽管 您可能会看到“参数”用于描述某些 文档):

function myFunction( myParameter ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction( "this string" );
> "The value is: this string."

如果省略了预期参数,生成的参数将包含 undefined 值,因为已向函数正文声明该参数,但 未使用值初始化:

function myFunction( myParameter ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction();
> "The value is: undefined."

您可以像 初始化变量:赋值运算符 (=) 后跟值。如果您 为该函数指定一个参数,新值会覆盖 默认值:

function myFunction( myParameter = "omitted" ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction( "this string" );
> "The value is: this string."

myFunction();
> "The value is: omitted."

非箭头的正文 函数还可以访问零索引、 类似于数组arguments 对象 包含作为参数传递的任何值,而无论函数 定义指定了参数:

function myFunction() {
   console.log( arguments );
};

myFunction( 3, true, "My string" );
> Arguments { 0: 3, 1: true, 2: "My string", … }

可变函数

借助 arguments 对象,您可以创建基本的变元函数, 接受可变数量的参数:

function myFunction() {
    let result = "";
    for (let i = 0; i < arguments.length; i++) {
        result += arguments[i] + " - ";
    }
    console.log( result );
};

myFunction( "My first string", "My second string", "my third string" );\
> "My first string - My second string - my third string - "

然而,现代 JavaScript 很少使用这种处理可变函数的方法, 开发。更常见的是 rest 参数语法 该函数会创建一个命名参数,并将其初始化为包含所有参数的数组 明确指定的属性之外:

function myFunction( mySeparator, ...myStrings ) {
  console.log( myStrings.join( mySeparator ) );
};

myFunction( " - ", "My first string", "My second string", "my third string" );
> "My first string - My second string - my third string"

parameter 绑定不同,REST 参数语法与箭头函数参数搭配使用时可按预期运行:

function myOuterFunction() {
    let myInnerArrowFunction = ( ...myParams ) => {
        console.log( myParams[ 0 ] );
    }
    myInnerArrowFunction( true );
};

myOuterFunction( false );
> true

let myArrowFunction = ( ...myParams ) => {
    console.log( myParams[ 0 ] );
};

myArrowFunction( true );
> true`
``