1

我有这段代码

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

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

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

变量 x = 100;

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

这个.x = 100

将 x 置于函数 f 的范围之外。如果是这样,它在哪里定义?以及如何访问它?

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

4

5 回答 5

4

该声明:

this.x = 100;

不在当前范围内创建变量,它x在任何对象this所指的对象上设置一个属性。在您的情况下this,将是刚刚通过 实例化的对象new f,该对象将由 . 返回f并分配给a.

当你说:

x = 20;

JavaScriptx在当前作用域中查找 a 并没有找到它,所以它在下一个作用域中查找,依此类推,直到它到达全局作用域。如果它在任何可访问的范围内都找不到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()thisf

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

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

进一步阅读:

于 2012-02-12T11:04:42.147 回答
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);
于 2012-02-12T09:30:53.323 回答
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) );
于 2012-02-12T09:43:12.420 回答
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
于 2012-02-12T10:27:24.303 回答
0

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

于 2012-02-12T09:30:55.903 回答