所以...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
不要拿 x
从 foo
在里面打电话 foo
?
1 - 是的我知道它是ES2015。
2 - 例A
3 - 例B
我的问题是,怎么做 this
玩这个?我不明白。他们是否真的在通话时评估?
是的,参数初始值设定项在调用时进行评估。 这很复杂,但步骤基本如下:
- 一个 新的执行上下文 在堆栈上建立,
用一个 新环境 在被调用函数的“闭包范围”中
- 如有必要,它就是
thisBinding
初始化
- 声明被实例化:
- 创建参数名称的可变绑定
- 如果有必要的话
arguments
对象创建一个绑定
- 该 绑定被迭代初始化 来自参数列表(包括所有解构等)
在此过程中, 评估初始化者
- 如果涉及任何闭包,则插入新环境
- 创建函数体中声明的变量的可变绑定(如果尚未通过参数名称完成)并使用初始化
undefined
- 绑定
let
和 const
创建函数体中的变量
- 函数的绑定(来自正文中的函数声明)使用实例化函数进行初始化
- 最后 评估函数的主体。
因此参数初始化者可以访问 this
和 arguments
调用,先前初始化的其他参数,以及处于“上限”词法范围内的所有内容。它们不受函数体中声明的变量的影响(尽管它们受所有其他参数的影响,即使它们的临时死区也是如此)。
那这个呢:
function bar (thing = x) {}
{
let x = 'x from foo';
return bar();
}
我不明白。为什么 bar
不要拿 x
从 foo
什么时候叫
内 foo
?
因为 x
是一个局部变量 bar
没有权限。我们很幸运,他们是 不动态范围!参数初始化程序不在调用站点评估,而是在被调用函数的作用域内评估。在这种情况下, x
标识符已解析为全局 x
变量。
当他们说“在通话时评估”时,我认为他们指的是一个 调用按姓名 表达。以下是babel输出您的第三个示例的方式:
'use strict';
var x = 'x from global';
function bar() {
var thing = arguments[0] === undefined ? x : arguments[0];
return thing;
}
function foo() {
var x = 'x from foo';
return bar();
}
bar() === foo(); // what?
以来 var x
是在词法范围内继承的 bar
来自全球范围,即使用范围。
现在,请考虑以下事项:
let i = 0;
function id() {
return i++;
}
function bar (thing = id()) {
return thing;
}
console.info(bar() === bar()); // false
这转化为
"use strict";
var i = 0;
function id() {
return i++;
}
function bar() {
var thing = arguments[0] === undefined ? id() : arguments[0];
return thing;
}
console.info(bar() === bar()); // false
注意这里怎么样 id
叫做 内 该函数,而不是在函数时被缓存和记忆 定义因此,按名称而不是按值调用。
所以这个行为 是 在第二个例子中实际上是正确的没有 y.foo
从那以后 this
是 动态范围 在Javascript中(即它根据给定函数调用的接收者而变化),何时 y.z()
寻找 this.foo
,它会寻找它 y
所以 y.z()
将返回 undefined
,而 x.foo()
只会归还 foo
功能本身。
如果你 做 想绑定到你可以绑定的接收器 foo
至 x
当你分配它。然后它应该按预期工作。
对不起,如果有任何不清楚的话;请在评论中告诉我,我很乐意澄清! :)