我有这段代码
var f = function() {
this.x = 100;
(
function() {
x = 20;
}
)();
};
var a = new f;
console.log(a.x);
我想知道为什么在全局范围内创建新变量x,输出为100,而不是20。 如果我写了
var x = 100;
嵌套函数会更改相同的x值。 似乎是通过
创建xthis.x = 100
将x置于函数f的范围之外。如果是这种情况,它在哪里定义?它怎么能被访问?
编辑:修正了错字:console.log(a.x)而不是console.log(x)
答案 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
的变量时,该变量在全局范围内。