javascript函数范围

时间:2010-02-19 09:45:14

标签: javascript

谁可以在此代码中解释为什么结果为[20,20,10,10]:

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

欢迎链接到规范

3 个答案:

答案 0 :(得分:7)

无法指明您的规格,但我强烈建议您阅读Douglas Crockford's "Javascript: The good parts"。本书将帮助您理解JavaScript的大多数奇怪但强大的功能。

截至您的问题:

  1. foo.bar(), this函数中的bar关键字绑定到foo object
  2. (foo.bar)()与上面相同,
  3. 在javascript中,您可以多次从右到左分配变量

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

  4. 函数是其他任何变量。因此,您要将函数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函数。

答案 1 :(得分:0)

我认为关注question会对此有所帮助。

答案 2 :(得分:0)

前两个函数调用是等效的。他们在foo的上下文中调用了bar的{​​{1}}方法 - 因此foo返回的值是this.x的{​​{1}属性,foo

后两个调用都是可疑/无效的语法。尝试通过JSLint运行代码,然后你会发出几个错误,然后完全窒息。我最好的猜测是,为什么他们返回x是因为它试图解析你的代码,在这种情况下它真的不应该并且让人感到困惑。可能会返回20,因为浏览器无法确定您要执行的操作,并且默认为10的值为10的全局(窗口)范围。这也可以解释Ramesh Vel的评论,即IE中的后两个值显示为x。由于语法无效,JavaScript的不同实现可能会以不同的方式处理它们。