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

2,286 阅读1分钟

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

var _default = (0, _helperPluginUtils().declare)((api, options) => {
    
})

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

问题

首先我们先来思考一个问题

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

a.foo();

foo1();

(0, a.foo)();

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

1

2

3

揭晓答案

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

a.foo()我们都能理解,a对象去调用foo的方法,所以this指向a。

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)(…)