`this`如何在默认参数中工作?

use*_*110 11 javascript default-parameters ecmascript-6

所以...ES6¹(几个小时前恰好标准化)为类似于PHP,Python等的函数带来了默认参数.我可以这样做:

function foo (bar = 'dum') {
    return bar;
}

foo(1); // 1
foo(); // 'dum'
foo(undefined); // 'dum'
Run Code Online (Sandbox Code Playgroud)

MDN表示在调用时评估参数的默认值.这意味着每次调用该函数时,'dum'都会再次计算表达式(除非实现执行一些我们不关心的奇怪的优化).

我的问题是,如何this发挥作用?

let x = {
  foo (bar = this.foo) {
    return bar;
  }
}

let y = {
  z: x.foo
}

x.foo() === y.z(); // what?
Run Code Online (Sandbox Code Playgroud)

babel转换器目前评估它为false,但我不明白.如果他们真的在通话时评估,那么:

let x = 'x from global';

function bar (thing = x) {
  return thing;
}

function foo () {
  let x = 'x from foo';
  return bar();
}

bar() === foo(); // what?
Run Code Online (Sandbox Code Playgroud)

babel转换器目前正在评估它true,但我没有得到它.为什么bar不采取xfoo内部调用时foo

1 - 是的我知道它是ES2015.
2 - 实施例A
3 - 实施例B.

Ber*_*rgi 11

我的问题是,如何this发挥作用?我不明白.他们是否真的在通话时评估?

是的,参数初始值设定项在调用时进行评估.这很复杂,但步骤基本如下:

  1. 一个新的执行上下文是建立在堆栈上,
    有一个新的环境中被调用函数的"关闭范围"
  2. 如有必要,它会thisBinding被初始化
  3. 声明被实例化:
    1. 创建参数名称的可变绑定
    2. 如有必要,将arguments创建一个绑定对象
    3. 绑定反复初始化从参数列表(包括所有destructurings等),
      在这个过程中,initialisers进行评估
    4. 如果涉及任何闭包,则插入新环境
    5. 创建函数体中声明的变量的可变绑定(如果尚未通过参数名称完成)并使用初始化 undefined
    6. 创建函数体中的绑定letconst变量
    7. 函数的绑定(来自正文中的函数声明)使用实例化函数进行初始化
  4. 最后评估函数体.

因此,参数初始化者可以访问调用thisarguments调用,先前初始化的其他参数以及处于"上限"词法范围内的所有内容.它们不受函数体中声明的变量的影响(尽管它们受所有其他参数的影响,即使它们的临时死区也是如此).

那这个呢:

function bar (thing = x) {}
{
  let x = 'x from foo';
  return bar();
}
Run Code Online (Sandbox Code Playgroud)

我不明白.为什么bar不采取xfoo内部调用时foo

因为xbar无权访问的局部变量.我们很幸运,他们没有动态范围!参数初始化程序不在调用站点评估,而是在被调用函数的作用域内评估.在这种情况下,x标识符将解析为全局x变量.