JavaScript 范围转移 - 帮助我理解

JavaScript scope shifting - Help me understand

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

它如何找到文件对这个问题无关紧要(假设它在 "scope" 之外)但是我试图通过逐步执行程序来理解它是如何工作的。

假设我也对此进行了一些简化;正如我所知,你们中的许多人可能会注意到我似乎在我请求加载数据和实际加载数据之间添加了一个不必要的层(显然我可以通过 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 对象的对象文字,这是一个很好的论据吗?)

现在,我从 FOO 调用 loadData,然后 Data 将调用 FOO 内部的 callack。我试过将其声明为 FOO.prototype.pareseData 和 FOO.parseData,但没有任何区别。

FOO.parseData = function(req,path) { 

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

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

一旦代码命中 FOO.parseData,它就会从 FOO 变为 "window"。

我不知道为什么...?

那是因为在 javascript 中,"this" 是对当前范围的引用,所以,如果您在原始范围之外调用 function/callback,很可能 "this" 将是 "window",因为 "window" 是调用 function/callback 的那个。

为了将 "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.

我强烈推荐你阅读这篇文章。

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

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

"上下文通常由函数的调用方式决定。当函数作为对象的方法被调用时,this 设置为调用该方法的对象:

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

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

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

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