另一个 TDZ 违规的例子是 ES6 中的参数默认值

    1. var b = 3;
    2. function foo( a = 42, b = a + b + 5 ) {
    3. // ..
    4. }

    b = a + b + 5在参数b(=右边的b,而不是函数外的那个)的TDZ中访问b,所以会出错。而访问 a 却没有问题,因为此时刚好跨出了参数 a 的 TDZ。
    在 ES6 中,如果参数被省略或者值为 undefined,则取该参数的默认值:

    1. function foo( a = 42, b = a + 1 ) {
    2. console.log( a, b );
    3. }
    4. foo(); // 42 43
    5. foo( undefined ); // 42 43
    6. foo( 5 ); // 5 6
    7. foo( void 0, 7 ); // 42 7
    8. foo( null ); // null 1

    表达式 a + 1 中 null 被强制类型转换为 0
    对 ES6 中的参数默认值而言,参数被省略或被赋值为 undefined 效果都一样,都是取该参数的默认值。然而某些情况下,它们之间还是有区别的:

    1. function foo( a = 42, b = a + 1 ) {
    2. console.log(
    3. arguments.length, a, b,
    4. arguments[0], arguments[1]
    5. );
    6. }
    7. foo(); // 0 42 43 undefined undefined
    8. foo( 10 ); // 1 10 11 10 undefined
    9. foo( 10, undefined ); // 2 10 11 10 undefined
    10. foo( 10, null ); // 2 10 null 10 null

    虽然参数 ab 都有默认值,但是函数不带参数时,arguments 数组为空。相反,如果向函数传递 undefined 值,则 arguments 数组中会出现一个值为 undefined 的单
    元,而不是默认值。
    ES6 参数默认值会导致 arguments 数组和相对应的命名参数之间出现偏差,ES5 也会出现 这种情况:

    1. function foo(a) {
    2. a = 42;
    3. console.log( arguments[0] );
    4. }
    5. foo( 2 ); // 42 (linked)
    6. foo(); // undefined (not linked)

    向函数传递参数时,arguments 数组中的对应单元会和命名参数建立关联(linkage)以得到相同的值。相反,不传递参数就不会建立关联。但是,在严格模式中并没有建立关联这一说:

    1. function foo(a) {
    2. "use strict";
    3. a = 42;
    4. console.log( arguments[0] );
    5. }
    6. foo( 2 ); // 2 (not linked)
    7. foo(); // undefined (not linked)

    因此,在开发中不要依赖这种关联机制。实际上,它是 js 语言引擎底层实现的一 个抽象泄漏(leaky abstraction),并不是语言本身的特性。
    arguments 数组已经被废止(特别是在 ES6 引入剩余参数...之后),在 ES6 之前,获得函数所有参数的唯一途径就是 arguments 数组。此外,即使将命名参数和 arguments 数组混用也不会出错,只需遵守一个原则,即不要同时访问命名参数和其对应的 arguments 数组单元。

    1. function foo(a) {
    2. console.log( a + arguments[1] ); // 安全!
    3. }
    4. foo( 10, 32 ); // 42