返回介绍

第一部分 类型和语法

第二部分 异步和性能

5.5 函数参数

发布于 2023-05-24 16:38:21 字数 2113 浏览 0 评论 0 收藏 0

另一个 TDZ 违规的例子是 ES6 中的参数默认值(参见本系列的《你不知道的 JavaScript(下卷)》的“ES6 & Beyond”部分):

var b = 3;

function foo( a = 42, b = a + b + 5 ) {
  // ..
}

b = a + b + 5 在参数 b (= 右边的 b ,而不是函数外的那个)的 TDZ 中访问 b ,所以会出错。而访问 a 却没有问题,因为此时刚好跨出了参数 a 的 TDZ。

在 ES6 中,如果参数被省略或者值为 undefined ,则取该参数的默认值:

function foo( a = 42, b = a + 1 ) {
  console.log( a, b );
}

foo();          // 42 43
foo( undefined );     // 42 43
foo( 5 );         // 5 6
foo( void 0, 7 );     // 42 7
foo( null );      // null 1

表达式 a + 1 中 null 被强制类型转换为 0 。详情请参见第 4 章。

对 ES6 中的参数默认值而言,参数被省略或被赋值为 undefined 效果都一样,都是取该参数的默认值。然而某些情况下,它们之间还是有区别的:

function foo( a = 42, b = a + 1 ) {
  console.log(
    arguments.length, a, b,
    arguments[0], arguments[1]
  );
}

foo();          // 0 42 43 undefined undefined
foo( 10 );        // 1 10 11 10 undefined
foo( 10, undefined );   // 2 10 11 10 undefined
foo( 10, null );    // 2 10 null 10 null

虽然参数 a 和 b 都有默认值,但是函数不带参数时,arguments 数组为空。

相反,如果向函数传递 undefined 值,则 arguments 数组中会出现一个值为 undefined 的单元,而不是默认值。

ES6 参数默认值会导致 arguments 数组和相对应的命名参数之间出现偏差,ES5 也会出现这种情况:

function foo(a) {
  a = 42;
  console.log( arguments[0] );
}

foo( 2 );   // 42 (linked)
foo();    // undefined (not linked)

向函数传递参数时,arguments 数组中的对应单元会和命名参数建立关联(linkage)以得到相同的值。相反,不传递参数就不会建立关联。

但是,在严格模式中并没有建立关联这一说:

function foo(a) {
  "use strict";
  a = 42;
  console.log( arguments[0] );
}

foo( 2 );   // 2 (not linked)
foo();    // undefined (not linked)

因此,在开发中不要依赖这种关联机制。实际上,它是 JavaScript 语言引擎底层实现的一个抽象泄漏(leaky abstraction),并不是语言本身的特性。

arguments 数组已经被废止(特别是在 ES6 引入剩余参数 ... 之后,参见本系列的《你不知道的 JavaScript(下卷)》的“ES6 & Beyond”部分),不过它并非一无是处。

在 ES6 之前,获得函数所有参数的唯一途径就是 arguments 数组。此外,即使将命名参数和 arguments 数组混用也不会出错,只需遵守一个原则,即不要同时访问命名参数和其对应的 arguments 数组单元

function foo(a) {
  console.log( a + arguments[1] ); // 安全!
}

foo( 10, 32 );  // 42

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文