2010-02-19 128 views
8

谁能解释为什么结果是[20,20,10,10]在此代码:javascript函数范围

var x = 10; 
var foo = { 
    x: 20, 
    bar: function() { 
    var x = 30; 
    return this.x; 
    } 
}; 

console.log(
    foo.bar(), 
    (foo.bar)(), 
    (foo.bar = foo.bar)(), 
    (foo.bar, foo.bar)() 
); 

链接规格欢迎

+0

在IE看来输出是20,20,undefined,undefined .. – RameshVel 2010-02-19 09:57:05

回答

7

不能指出你的规格,但我强烈推荐阅读Douglas Crockford's "Javascript: The good parts"。本书将帮助您理解JavaScript的大部分奇怪但强大的功能。

作为你的问题:

  1. foo.bar(),在bar功能 this关键字被绑定到对象foo
  2. (foo.bar)()是与上述相同,
  3. 在JavaScript中,您可以多次指定从右到左的变量

    z = 3; x =(y = z); console.log(x); // 3

函数作为其他任何变量。因此,您将函数foo.bar分配给foo.bar,但括号会使分配的函数返回并执行。

(foo.bar = foo.bar)(); 
//is the same as 
var f = (foo.bar = foo.bar); 
f(); 
//and this also the same as: 
var f= foo.bar; 
f(); 

该函数返回从括号没有绑定到任何东西,所以this将引用全局对象,在浏览器的情况下 - 在window对象。

4。该条款(foo.bar,foo.bar)()仅仅是相似:

a = (3, 4); //last value is returned, first just parsed. 
//a contains 4 

var f = (foo.bar, foo.bar); 
//f contains body of foo.bar function, 
f() // is executed in the context of `global` object, eg. `window`. 

请阅读的JavaScript功能有关binding

0

我认为以下question会有所帮助为了这。

0

前两个函数调用是等价的。他们在foo的范围内调用foobar方法 - 因此this.x返回的值是foox属性的值,即20

后面两个调用都是有问题/无效的语法。试着通过JSLint运行你的代码,你会发现它出现了几个错误,然后完全窒息。我最好的猜测,为什么他们返回10是它试图解析你的代码的情况下,它真的不应该和困惑。 10可能会返回,因为浏览器无法弄清楚您要做什么,并且默认为x的值为10的全局(窗口)范围。这也解释了Ramesh Vel的评论,其中的第二个值在IE中出现为undefined。由于语法无效,JavaScript的不同实现可能会以不同的方式处理它们。