所以... 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
,但我不明白。为什么 bar
在 foo
内部调用时不从 foo
中获取 x
?
最佳答案
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 , 但步骤基本如下:
- A new execution context建立在栈上,
用new environment在被调用函数的“闭包范围”中 - 如有必要,请输入
thisBinding
is initialised - Declarations are instantiated :
- 创建参数名称的可变绑定(bind)
- 如有必要,将创建一个
arguments
对象并绑定(bind) - bindings are iteratively initialised来自参数列表(包括所有解构等)
在此过程中,initialisers are evaluated - 如果涉及任何关闭,则插入一个新环境
- 创建函数体中声明的变量的可变绑定(bind)(如果尚未通过参数名称完成)并使用
undefined
初始化 - 为函数体中的
let
和const
变量创建绑定(bind) - 函数的绑定(bind)(来自主体中的函数声明)使用实例化函数进行初始化
- 最后 body of the function is evaluated .
所以参数初始化器确实可以访问调用的 this
和 arguments
,可以访问先前初始化的其他参数,以及它们“上层”词法范围内的所有内容.它们不受函数体中声明的变量的影响(尽管它们受所有其他参数的影响,即使在它们的暂时死区中也是如此)。
what about this:
function bar (thing = x) {} { let x = 'x from foo'; return bar(); }
I don't get it. Why does
bar
not take thex
fromfoo
when called insidefoo
?
因为 x
是 bar
无权访问的局部变量。我们很幸运,他们是not dynamically scoped !参数初始值设定项不在调用站点评估,而是在被调用函数的范围内评估。在这种情况下,x
标识符被解析为全局 x
变量。
关于javascript - `this` 在默认参数下如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30901648/