2012-02-12 57 views
1

我有这样一段代码从自参照的成员变量调用嵌套函数

var f = function() { 
    this.x = 100; 
    (
     function() { 
      x = 20; 
     } 
    )(); 
}; 

var a = new f; 
console.log(a.x); 

我想知道为什么在全局范围内创建一个新的变量x,并且输出是100,而不是20。 如果我写

var x = 100;

嵌套函数改变相同的x值。 似乎经由

this.x = 100

地方函数f的范围之外X创建X。如果是这样的话,它在哪里定义?它如何被访问?

编辑:固定一个错字:的console.log(a.x)代替的console.log(x)的

回答

4

声明:

this.x = 100; 

不创建在当前范围内的变量,它设置在任何物体this是指财产x。在你的情况下,this将是刚刚通过new f实例化的对象,该对象将由f返回并分配给a

当你说:

x = 20; 

的JavaScript会在当前范围的x并没有找到它,所以它看起来在未来的范围了,等等,直到它得到了全球范围内。如果它没有在任何可访问的范围中找到x,它会创建一个新的全局变量,如您所见。

要从嵌套函数内访问属性x通常的做法是,以基准存储this在一个局部变量,然后将嵌套函数可以引用变量:

var f = function() { 
    var self = this;  // keep a reference to this 

    this.x = 100; 
    (
     function() { 
      self.x = 20; // use the self reference from the containing scope 
     } 
    )(); 
}; 

var a = new f; 
console.log(a.x);   // will now be 20 

其他的方法来做到它是引用this.x在内部函数,提供你通过.call() method调用内部函数,这样就可以显式地设置this是一样的,在(外)f功能:

var f = function() { 
    this.x = 100; 
    (
     function() { 
      this.x = 20; 
     } 
    ).call(this); 
}; 

var a = new f; 
console.log(a.x); 

延伸阅读:

+0

很好的解释,并且还教我call()方法! – kaustubh 2012-02-12 13:31:58

1

在JavaScript中,变量具有功能级范围。此外,这样的:

this.x = 100; 

从不同的充:

x = 20; 

因为在后一种情况下,x具有全局例如,它成为window对象的一部分(您以前没有它曾经var)范围。


而且当你正在做的:

var a = new f; 
console.log(a.x); 
+0

这是一个错字,我的意思的console.log(a.x),对不起。 – kaustubh 2012-02-12 10:01:19

+0

任何使'x = 20'参考'this.x'而不是在全局范围内创建新'x'的方法? – kaustubh 2012-02-12 10:13:46

0

当你声明的变量,而不var

var a = new f; 
console.log(x); 

,而你是suppossed做您正在访问通过x = 20;设置全局变量x ,该变量在全局范围内。

+0

是的,但它的父范围确实有一个名为x的变量(通过this.x声明和定义)。它应该不是指那个?或者,这个.x是否有效地在别处声明了它? – kaustubh 2012-02-12 10:27:45

+1

'this.x'不是一个变量。 – georg 2012-02-12 10:30:22

+0

@kaustubh不,它不是指那个。 – xdazz 2012-02-12 10:34:33

1
var f = function() { 

    this.x = 100; 
    console.log(this); 
    // f 

    (function() { 
     console.log(this); 
     // DOMWindow. So x is a property of window because you're not declaring it with var 
     x = 20; 
    })(); 
}; 

,如果你想匿名函数的产品分配到的f范围,然后下面的工作:

var f = function() { 
    this.x = (function() { 
     var x = 20; // Local scope 
     return x; 
    })(); 
}; 

console.log((new f().x)); 
1

如果你想在一个嵌套的,匿名的子功能改变的成员函数,你可能希望创建一个指向“这个”范围之内,具体如下:

var f = function() { 
    this.x = 100; // set the member value 
    var self = this; // pointer to the current object within this function scope 
    (
     function(){ 
      self.x = 20; // 'self' is in scope 
     }(); 
    )(); 
}; 

var a = new f; 

console.log(a.x); // Output: 20