javascript - `this` 在默认参数下如何工作?

标签 javascript ecmascript-6 default-parameters

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

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

foo(1); // 1
foo(); // 'dum'
foo(undefined); // 'dum'

MDN 说参数的默认值是在调用时求值的。这意味着每次我调用函数时,表达式 'dum' 都会被再次求值(除非实现做了一些我们不关心的奇怪的优化)。

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

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

let y = {
  z: x.foo
}

x.foo() === y.z(); // what?

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?

babel 转译器当前评估³它为 true,但我不明白。为什么 barfoo 内部调用时不从 foo 中获取 x

<子> 1 - 是的,我知道它是 ES2015。
2 - Example A
3 - Example B

最佳答案

My question is, how does this play into this? I don't get it. Are they are really evaluated at call time?

是的,参数初始值设定项在调用时计算。 It's complicated , 但步骤基本如下:

  1. A new execution context建立在栈上,
    new environment在被调用函数的“闭包范围”中
  2. 如有必要,请输入 thisBinding is initialised
  3. Declarations are instantiated :
    1. 创建参数名称的可变绑定(bind)
    2. 如有必要,将创建一个 arguments 对象并绑定(bind)
    3. bindings are iteratively initialised来自参数列表(包括所有解构等)
      在此过程中,initialisers are evaluated
    4. 如果涉及任何关闭,则插入一个新环境
    5. 创建函数体中声明的变量的可变绑定(bind)(如果尚未通过参数名称完成)并使用 undefined 初始化
    6. 为函数体中的 letconst 变量创建绑定(bind)
    7. 函数的绑定(bind)(来自主体中的函数声明)使用实例化函数进行初始化
  4. 最后 body of the function is evaluated .

所以参数初始化器确实可以访问调用的 thisarguments,可以访问先前初始化的其他参数,以及它们“上层”词法范围内的所有内容.它们不受函数体中声明的变量的影响(尽管它们受所有其他参数的影响,即使在它们的暂时死区中也是如此)。

what about this:

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

I don't get it. Why does bar not take the x from foo when called inside foo?

因为 xbar 无权访问的局部变量。我们很幸运,他们是not dynamically scoped !参数初始值设定项不在调用站点评估,而是在被调用函数的范围内评估。在这种情况下,x 标识符被解析为全局 x 变量。

关于javascript - `this` 在默认参数下如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30901648/

相关文章:

javascript - Openlayers 3 交互.draw()

javascript - 用空格或字符分隔文本并包含该字符

javascript - import * vs import { specificName } 在 Typescript/ES6 中?

php - 在 PHP 中为我的类方法提供默认对象

c++ - 在其自身的默认值中使用参数名称 - 合法吗?

c++ - 默认模板参数偏特化

Javascript解构以填充现有对象

javascript - 摆脱不相关的控制台错误(404(未找到))

javascript - javascript中的多个嵌套函数

javascript - 有什么方法可以在 React 中定义类似于 Angular 的自定义属性吗?