从自调用嵌套函数引用成员变量

时间:2012-02-12 09:27:25

标签: javascript nested-function

我有这段代码

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

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

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

  

var x = 100;

嵌套函数会更改相同的x值。 似乎是通过

创建x
  

this.x = 100

将x置于函数f的范围之外。如果是这种情况,它在哪里定义?它怎么能被访问?

编辑:修正了错字:console.log(a.x)而不是console.log(x)

5 个答案:

答案 0 :(得分:4)

声明:

this.x = 100;

不在当前范围内创建变量,它会在x引用的任何对象上设置属性this。在您的情况下,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);

进一步阅读:

答案 1 :(得分:1)

在javascript中,变量具有功能级范围。另外,这个:

this.x = 100;

与以下内容不同:

x = 20;

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


当你这样做的时候:

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

您正在访问通过x设置的全局变量x = 20;,但您可以这样做:

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

答案 2 :(得分: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) );

答案 3 :(得分:1)

如果要在嵌套的匿名子函数中更改成员函数,可能需要在范围内创建指向“this”的指针,如下所示:

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

答案 4 :(得分:0)

当您声明一个没有var的变量时,该变量在全局范围内。