JavaScript范围转移 - 帮助我理解

时间:2015-04-15 13:07:56

标签: javascript oop scope

我正在创建一个程序,最终将创建数千个小对象(理想情况下大约有60,000个),每个对象都包含特定信息。它将从一个已经创建的小JSON文件加载每个对象,并且位于服务器上的目录树结构中。

如何找到文件对这个问题无关紧要(让我们说它超出了它的“范围”)但是我试图通过逐步完成程序来理解它是如何工作的。

假设我也稍微简化了一下;我知道很多人可能会发现我似乎在我的加载数据和实际加载它的请求之间添加了一个不必要的层(显然我可以通过jQuery的$ .getJSON()。done()),但是因为这是要考虑文件系统结构,程序也需要处理该部分。

Data = function() {

    var VERSION = 1.1;

    if (this.constructor === Data) {

        throw new Error("Objects may not be directly instantiated from an abstract class.");
    }
}

// Loads a file with the path from the root set in config.json

Data.prototype.loadData = function(treePath,callback) {

    // does data loading stuff here and proceeds through, eventually getting to this line: 
            callback(req,loadedData);

}

现在,我在那里有一个抽象层 - 我不希望Data对象本身就被创建,这就是为什么它会抛出错误,如果有人调用“new Data();”那是故意的。

然后我会有两个继承Data的对象;两种方法都以不同的方式处理加载的数据。但是,由于文件树结构对于两者都是相同的,因此创建要继承的抽象对象是有意义的。 (或者,作为一个子问题,这对于Data对象的对象文字是一个很好的参数吗?)

现在,我从FOO调用loadData,然后Data将调用calock,它位于FOO内部。我已经尝试将其声明为FOO.prototype.pareseData和FOO.parseData,它没有任何区别。

FOO.parseData = function(req,path) { 

    // Parse the data and deal with it as needed.
}

单步执行,当我从主程序中调用FOO并告诉它开始加载数据时,我可以看到“this”值。最初,这= FOO,正如预期的那样;这仍然是FOO,直到Data调用回调函数。

一旦代码命中FOO.parseData,这将从FOO变为“window”。

我不知道为什么......?

2 个答案:

答案 0 :(得分:1)

那是因为在javascript中,"这个"是对当前范围的引用,因此,如果在原始范围之外调用函数/回调,很可能是" this"将是"窗口",因为"窗口"是调用函数/回调的那个。

一种解决方法,以维持"这个"在您声明它的范围内,您必须将函数绑定到给定范围:

function Foo() {
    this.bar();
}.bind(this); //-> Here you bind Foo to the current scope, so inside Foo, this will be always the scope where it was bound.

答案 1 :(得分:1)

我强烈建议您阅读本文。

http://ryanmorr.com/understanding-scope-and-context-in-javascript/

您的问题在第3段中解释 - 什么是“此”上下文

"上下文通常取决于函数的调用方式。当一个函数作为一个对象的方法被调用时,它被设置为调用该方法的对象:

var obj = {
    foo: function(){
        alert(this === obj);    
    }
};
obj.foo(); // true

当使用new运算符调用函数来创建对象的实例时,同样的原则也适用。以这种方式调用时,函数范围内的this值将设置为新创建的实例:

function foo(){
    alert(this);
}
foo() // window
new foo() // foo

当作为未绑定函数调用时,它将默认为浏览器中的全局上下文或窗口对象。但是,如果函数在严格模式下执行,则上下文将默认为undefined。"