特殊的JavaScript构造:对象定义中对象类型的变量

时间:2011-12-22 15:34:49

标签: javascript

好的,我偶然发现了这段代码..

为什么会这样? JavaScript使用什么样的邪恶方案来解决变量?

我看待它的方式,作为一个C ++类型的人:类/对象定义包含对正在定义的类的对象的不存在的引用。说真的,怎么样?

(老实说,我部分理解 - 我可以推断出一个关于JS如何以及何时解析名字的草编概念......但也许这样一来,这个问题对其他人来说会更有用,有朝一日)

有罪代码:

function Sio() {
    this.someValue = 5;
    this.doStuff = function() {
        console.log("look: "+howDoYouResolveThisYouFoulCreature.someValue);
    };
}

var howDoYouResolveThisYouFoulCreature = new Sio();

这似乎是错误的。

3 个答案:

答案 0 :(得分:3)

这里有很多概念,我不确定哪一个给你带来麻烦......

最可能的两个是new / thisvar

new / this

调用函数时,this的值由您调用它的上下文决定。

如果使用new关键字,则创建该函数的实例并将该实例作为上下文。

当您致电howDoYouResolveThisYouFoulCreature.doStuff()时,您正在以全局形式访问该实例。通常会更有意义:

this.doStuff = function() {
    console.log("look: "+ this.someValue);
};

由于foo.doStuff()使foo成为doStuff()调用的上下文(这使得函数可以在Sio的不同实例之间重复使用)

<强> var

  1. JavaScript中的范围处于功能级别。
  2. 在函数内的任何位置使用var something将该变量范围限定为该函数
  3. 在函数顶部使用单个var语句以避免混淆被认为是一种好习惯
  4. 此外,在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 可能的位置,在某些时候,可以定义。在调用函数之前,不会解析变量,此时可以定义它。或不。没什么大不了的。 : - )