Javascript 为什么babel会将导入的函数调用重写为(0,fn)(…)?
给定一个输入文件,如Javascript 为什么babel会将导入的函数调用重写为(0,fn)(…)?,javascript,ecmascript-6,babeljs,Javascript,Ecmascript 6,Babeljs,给定一个输入文件,如 从'b'导入{a}; 函数x(){ () } 巴贝尔将把它编译成 “严格使用”; var_b=要求('b'); 函数x(){ (0,_b.a)(); } 但在松散模式下编译时,函数调用输出为\u b.a() 我对逗号操作符的添加位置做了一些研究,希望能有一条注释来解释它。 负责添加它的代码是。(0,\u b.a)(确保调用函数\u b.a时将设置为全局对象(或者如果启用了严格模式,则将设置为未定义的)。如果要直接调用\u b.a(),则将\u b.a设置为\u b时调用
从'b'导入{a};
函数x(){
()
}
巴贝尔将把它编译成
“严格使用”;
var_b=要求('b');
函数x(){
(0,_b.a)();
}
但在松散模式下编译时,函数调用输出为\u b.a()代码>
我对逗号操作符的添加位置做了一些研究,希望能有一条注释来解释它。
负责添加它的代码是。(0,\u b.a)(
确保调用函数\u b.a
时将设置为全局对象(或者如果启用了严格模式,则将设置为未定义的)。如果要直接调用\u b.a()
,则将\u b.a
设置为\u b
时调用\u b.a
(0,_b.a)()代码>相当于
0; // Ignore result
var tmp = _b.a;
tmp();
(,
是逗号运算符,请参阅)
逗号运算符计算其每个操作数(从左到右)
并返回最后一个操作数的值
让我们来看一个例子:
var a = {
foo: function() {
console.log(this === window);
}
};
a.foo(); // Returns 'false' in console
(0, a.foo)(); // Returns 'true' in console
现在,在foo
方法中,this
等于a
(因为foo
附加到a
)。所以,如果您直接调用a.foo(
),它将在控制台中记录false
但是,如果您被调用(0,a.foo)(
)。表达式(0,a.foo)
将计算其每个操作数(从左到右),并返回最后一个操作数的值。换句话说,(0,a.foo)
相当于
function() {
console.log(this === window);
}
由于此函数不再附加到任何对象,因此其this
是全局对象窗口
。这就是为什么调用(0,a.foo)(
以这种迂回的方式调用函数时,它会在控制台中记录true
:
(throwAwayValueHere, fn)(args);
工作原理如下:
- 逗号表达式
throwayValuehere,fn
被计算:逗号运算符计算其第一个操作数,丢弃该值,然后计算其第二个操作数,并将该值作为其结果
- 然后将该值作为函数调用,并传入参数
这样做在两种情况下都会产生影响:
一,。如果函数位于对象属性上,例如:
(throwAwayValueHere, obj.fn)(args);
在函数调用过程中,它调用函数时未将this
设置为obj
;相反,它被设置为默认值,要么是全局this
值(window
在浏览器上),要么是严格模式下的undefined
例如:
“严格使用”;
常量对象={
价值:42,
fn:函数(){
log(`typeof this=${typeof this}`);
如果(此类型==“对象”){
log(`this.value=${this.value}`);
}
}
};
//正常通话:
log(`obj.fn():`);
obj.fn();
//间接呼叫:
log(`(0,obj.fn)(:`);
(0,obj.fn)()
他们应该做\u b.a.call()
来明确目的。@Bergi我确信他们使用(0,)的原因是为了在传输的代码中节省空间。另请参阅,谢谢链接。我想在文件的顶部添加var\u a=(0,\u b.a)
,然后调用\u a
会在很多情况下节省更多空间,你知道他们没有这样做吗?@Andy你的建议可能会有副作用,例如当\u b.a
是(动态)getter。@RobW我明白了,所以你说的想法是在需要调用函数之前避免潜在的副作用。注意,模块总是严格的代码,所以总是this===未定义的
,你甚至不需要提及全局objectrunningconsole.log(this==窗口)
在开发人员控制台中不再记录打印。这让我大吃一惊。这里的关键是逗号运算符“返回最后一个操作数的值”-“值”在这里是函数本身,不包含其父函数-因此foo不再存在于。
(throwAwayValueHere, obj.fn)(args);