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

发布于 2025-01-04 13:58:59 字数 473 浏览 2 评论 0 原文

我有这段代码,

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

这个.x = 100

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

编辑:修复了一个拼写错误:console.log(ax) 而不是 console.log(x)

I have this piece of code

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

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

I am wondering why a new variable x is created at global scope, and the output is 100, not 20.
If I write instead

var x = 100;

the nested function changes the same x's value.
It seems that creating x via

this.x = 100

places x outside the scope of function f. If that is the case, where is it defined? And how can it be accessed?

EDIT : Fixed a typo : console.log(a.x) instead of console.log(x)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

满地尘埃落定 2025-01-11 13:58:59

该语句:

this.x = 100;

不在当前作用域中创建变量,而是在 this 引用的任何对象上设置属性 x。在您的情况下,this 将是刚刚通过 new f 实例化的对象,该对象将由 f 返回并分配给 一个。

当你说:

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() 方法,以便您可以显式设置 this 与(外部)f 中的相同 函数:

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

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

进一步阅读:

The statement:

this.x = 100;

Does not create a variable in the current scope, it sets a property x on whatever object thisrefers to. In your case this will be the object just instantiated via new f, the same object that will be returned by f and assigned to a.

When you say:

x = 20;

JavaScript looks for an x in the current scope and doesn't find it, so it looks in the next scope up, etc., until it gets to the global scope. If it doesn't find x in any accessible scope it creates a new global variable as you have seen.

To access the property x from within a nested function the usual practice is to store a reference to this in a local variable and then the nested function can reference that variable:

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

The other way to do it is to reference this.x in the inner function, provided you call the inner function via the .call() method so that you can explictly set this to be the same as in the (outer) f function:

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

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

Further reading:

柠檬 2025-01-11 13:58:59

在 JavaScript 中,变量具有函数级作用域。另外,这:

this.x = 100;

与:不同,

x = 20;

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


另外,当您执行以下操作时:

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

您正在访问通过 x = 20; 设置的全局变量 x,而您应该执行以下操作:

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

In javascript, variables have function-level scope. Also, this:

this.x = 100;

is differnt from:

x = 20;

because in later case, x has global (you have not used var before it) scope eg it becomes part of window object.


Also when you are doing:

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

You are accessing global variable x set via x = 20; whereas you are suppossed to do:

var a = new f;
console.log(a.x);
败给现实 2025-01-11 13:58:59
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) );
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;
    })();
};

if you want to assign the product of the anonymous function to the scope of f then the following will work:

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

console.log( (new f().x) );
计㈡愣 2025-01-11 13:58:59

如果要更改嵌套匿名子函数中的成员函数,您可能需要在作用域内创建指向“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

If you want to change a member function in a nested, anonymous subfunction, you might want to create a pointer to 'this' within scope, as follows:

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
听闻余生 2025-01-11 13:58:59

当您声明不带 var 的变量时,该变量位于全局范围内。

When you declare a variable without var, the variable is in global scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文