(0,fn)()的执行原理

今天在看babel插件的源码的时候,发现Babel的不少插件都是这样是写的。api

var _default = (0, _helperPluginUtils().declare)((api, options) => {
    
})
复制代码

咦,这个(0,_helperPluginUtils().declare)是什么意思呢? 怎么用呢? 本着求知的精神,在网上查了下。bash

问题

首先咱们先来思考一个问题babel

const a = {
    foo: function () {
        console.log(this === window);
    }
};
const  foo1 = a.foo;

a.foo();

foo1();

(0, a.foo)();

复制代码

给你三秒钟时间,思考下a.foo(),foo1()和(0,a.foo)() 分别会输出什么?this

1spa

2插件

3code

揭晓答案对象

a.foo(),foo1()和(0,a.foo)() 分别会输出false,true和true。ip

a.foo()咱们都能理解,a对象去调用foo的方法,因此this指向a。get

foo1() 由于下面的代码不在严格模式下,且 this 的值不是由该调用设置的,因此 this 的值默认指向全局对象。

逗号操做符

(0,a.foo)() 的this的为何是window呢?这是由于逗号操做符的运行规则。

逗号操做符 对它的每一个操做数求值(从左到右),并返回最后一个操做数的值。

这句话怎么理解呢?看下面的代码

console.log((1, 2));   // 返回最后一个操做数的值 => 2
console.log((a = b = 3, c = 4));   // 返回最后一个操做数的值 => 4
复制代码

因此 (0, a.foo)(), 其实等于

0;
var temp = a.foo;
temp();

复制代码

由于逗号操做符的运行规则,对它的每一个操做数求值(从左到右),并返回最后一个操做数的值。(0, a.foo)返回了_foo,而后_foo在全局环境里面调用,因此this指向window

为何要这样作呢?

这样作是为了将a.foo的this设置为window(在严格模式下为undefined)

若是直接调用a.foo的话a.foo里面的this将指向a。

参考资料
逗号操做符

Why does babel rewrite imported function call to (0, fn)(…)

相关文章
相关标签/搜索