2012-03-16 80 views
10

在调查谷歌Plusone精选剧本,我看到下面的语法很多次:使用这种语法的原因是什么(0,_.Em)();

(0, _.Em)(); 

假设_.Em是一个功能上面的语句将导致调用该函数,这是很明显的。另一方面,如果它不确定,那么结果是否与简单地使用_.Em()相同?

任何人都可以阐明使用这种语法背后的想法吗?

+0

另请参阅[逗号运算符是否影响Javascript中的执行上下文?](http://stackoverflow.com/q/36076794/1048572) – Bergi 2016-09-16 12:29:33

回答

8

基本上,该语法允许在window对象的上下文中调用_.Em()而不是_

假设你有这样的代码:

Foo = function() { 
    this.foo = "foo"; 
}; 

Foo.prototype.Em = function() { 
    alert(this.foo); 
}; 

var _ = new Foo(); 

发行_.Em()将导致Em()被称为在_上下文。在函数内部,this关键字将引用_,因此foo将被打印。

发出(0, _.Em)()将来自对象的方法调用解耦并在全局上下文中执行调用。在函数内部,this关键字将引用window,因此undefined将被打印,因为window不具有foo属性。

您可以测试this fiddle中两种语法之间的差异。

+0

但是为什么((0,_.EM)()那? – Niko 2012-03-16 10:46:05

+5

因为计算'_.Em',所以应用调用操作符与直接调用'_.Em()'不一样。评估'_.Em'独立地返回一个“自由函数”,因为没有更好的术语,并且该函数不再与'_'对象绑定。同样的结果可以通过写'var f = _.Em; F();'。在这两种情况下,'this'关键字将在函数内引用'window'而不是'_'。 – 2012-03-16 10:50:14

+0

+1,很好的答案。我想补充一点,这也许是我在JS中见过的最无意义的句法糖的形式。 '(0,)()'的长度与'.call()'的长度完全相同,所以没有字节保存,除非你在逗号后删除空格(甚至只有一个)。以混淆毫无戒心的开发者为代价,使用这样的语法似乎并不值得。 – 2012-03-16 10:50:51