好的,我偶然发现了这段代码..
为什么会这样? JavaScript使用什么样的邪恶方案来解决变量?
我看待它的方式,作为一个C ++类型的人:类/对象定义包含对正在定义的类的对象的不存在的引用。说真的,怎么样?
(老实说,我部分理解 - 我可以推断出一个关于JS如何以及何时解析名字的草编概念......但也许这样一来,这个问题对其他人来说会更有用,有朝一日)
有罪代码:
function Sio() {
this.someValue = 5;
this.doStuff = function() {
console.log("look: "+howDoYouResolveThisYouFoulCreature.someValue);
};
}
var howDoYouResolveThisYouFoulCreature = new Sio();
这似乎是错误的。
答案 0 :(得分:3)
这里有很多概念,我不确定哪一个给你带来麻烦......
最可能的两个是new
/ this
和var
。
new
/ this
调用函数时,this
的值由您调用它的上下文决定。
如果使用new
关键字,则创建该函数的实例并将该实例作为上下文。
当您致电howDoYouResolveThisYouFoulCreature.doStuff()
时,您正在以全局形式访问该实例。通常会更有意义:
this.doStuff = function() {
console.log("look: "+ this.someValue);
};
由于foo.doStuff()
使foo
成为doStuff()
调用的上下文(这使得函数可以在Sio
的不同实例之间重复使用)
<强> var
强>
var something
将该变量范围限定为该函数var
语句以避免混淆被认为是一种好习惯此外,在doStuff
具有值之前,不会调用howDoYouResolveThisYouFoulCreature
函数。在此之前,重要的是函数在语法上是正确的,变量的类型无关紧要。
答案 1 :(得分:1)
它的工作原理是因为在创建howDoYouResolveThisYouFoulCreature之前不执行function()this.doStuff。请记住,你做的任何新的Sio()都将总是console.log,无论调用doStuff()的变量名称如何,都要记得howDoYouResolveThisYouFoulCreature.someValue。
答案 2 :(得分:1)
这是因为:
var howDoYouResolveThisYouFoulCreature = new Sio();
......实际上已经解决了:
var howDoYouResolveThisYouFoulCreature;
howDoYouResolveThisYouFoulCreature = new Sio();
因此,在分配函数 doStuff
时,var
已经被声明。
编辑:忘记这一点,我是愚蠢的。事实证明pimvdb是正确的,这是证据(also on jsfiddle):
function A() {
this.logValue = function() {
if (b === undefined) {
console.log('Wah, wah, wah...');
} else {
console.log(b.someValue);
}
};
}
function B() {
this.someValue = 42;
}
var a = new A();
a.logValue(); // Wah, wah, wah...
var b = new B();
a.logValue(); // 42
因此执行上下文是关键。在构建Sio
(或者,在这种情况下,A
)时,它的范围限定在b
可能的位置,在某些时候,可以定义。在调用函数之前,不会解析变量,此时可以定义它。或不。没什么大不了的。 : - )