我似乎无法理解JavaScript变量的特定范围。与我发现的其他示例和问题不同,我对嵌套函数的范围感兴趣。
我在this JSFiddle设置了一个示例。相关部分如下:
function MyObject() {
var self = this;
var a = 1;
this.b = 2;
var innerMethod = function() {
//1 and 2: direct reference
logMessage("a = " + a); // a = 1
//logMessage("b = " + b); // Error: b is not defined
//3 and 4: using this
logMessage("this.a = " + this.a); // this.a = undefined
logMessage("this.b = " + this.b); // this.b = undefined
//5 and 6: using self
logMessage("self.a = " + self.a); // self.a = undefined
logMessage("self.b = " + self.b); // self.b = 2
}
}
现在,我了解对a
的引用直接有效。
我也理解消息3和4(this.a
和this.b
)将失败,因为this
指的是内部函数。我也理解第6行是有效的,因为我保存了对原始对象的引用。
我不明白的是:
答案 0 :(得分:4)
a
变量就是变量。它在innerMethod
(它只是一个嵌套函数)的范围内可见,如a
,它是如何声明的(即JavaScript具有词法作用域规则,内部函数可以看到函数的变量)它们是在里面定义的。
this
与MyObject
构造函数的本地范围不同。
您已经看到self
是this
MyObject
的别名,而innerMethod
已在其自己的范围内覆盖this
。尽管如此,由于this
不是函数范围的别名,因此self.a
和this.a
都不会在这里工作。
有关词汇范围的更严格的解释,您可以例如从维基百科开始:http://en.wikipedia.org/wiki/Scope_(computer_science)
您可以在ECMA标准http://es5.github.com/#x10.3
中了解执行上下文和标识符解析规则答案 1 :(得分:1)
这是范围的问题,当创建函数时,它们会保存周围环境(包括变量)。
因此,在创建innerMethod
时,它可以看到变量self
和a
。
一个重要的概念是,在声明函数时创建范围,而不是在调用函数时创建范围。
在您的情况1中,b
未被声明(此对象不相同)。
在案例5和案例6中,您没有创建self.a
。
答案 2 :(得分:0)
主要原因是self
在 innerMethod 范围内不等于this
。 this
是引用该函数所有者的关键字。对于 innerMethod ,它不是实例方法,它属于Window。
function MyObject() {
var self = this;
var innerMethod = function() {
alert("inner method, self == this?: " + self == this); // false
alert("inner method: " + this); // [object Window]
alert("closest constructor name of in prototype chain ?: "+ this.__proto__.constructor.name); // Window
}
this.outerMethod = function(){
innerMethod();
alert("outer method: " + this); // [object MyObject]
alert("closest constructor name in prototype chain?: "+ this.__proto__.constructor.name); // MyObject
}
}
var o = new MyObject();
o.outerMethod();
您可以在here
进行游戏