今天在看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)); // 返回最后一个操作数的值 => 2console.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。
参考资料