Javascript 运行回调时丢失对JS类中函数的访问

Javascript 运行回调时丢失对JS类中函数的访问,javascript,class,tvml,tvjs,Javascript,Class,Tvml,Tvjs,我正在开发一个TVML/TVJS应用程序,在使用Javascript类时遇到了一个问题 我的启动application.js文件调用一个函数 resourceLoader = new ResourceLoader(); resourceLoader.getHomeScreen(); 我有一个名为ResourceLoader.js的单独文件,其中包含以下内容: class ResourceLoader { getHomeScreen() { var homeData = BASEURL

我正在开发一个TVML/TVJS应用程序,在使用Javascript类时遇到了一个问题

我的启动application.js文件调用一个函数

resourceLoader = new ResourceLoader();
resourceLoader.getHomeScreen();
我有一个名为ResourceLoader.js的单独文件,其中包含以下内容:

class ResourceLoader {

getHomeScreen() {
    var homeData = BASEURL + "/home.json";
    var homeTemplate = BASEURL + "/home.tvml";

    this.getRemoteJSON(homeData, homeTemplate, this._jsonLoaded);
}

_jsonLoaded(template, jsonString) {
    var parsedJSON = JSON.parse(jsonString);
    this.getRemoteXMLFile(template, parsedJSON);
}

getRemoteJSON(file, template, callback) {
    var xhr = new XMLHttpRequest();
    xhr.responseType = "text";
    xhr.addEventListener("load", function() {
        callback(template, xhr.responseText);
    }, false);
    xhr.open("GET", file, true);
    xhr.send();
}

getRemoteXMLFile(template, json) {
    var xhr = new XMLHttpRequest();
    xhr.responseType = "xml";
    xhr.addEventListener("load", function() {
        loadRemoteFile(xhr.responseText, json);
    }, false);
    xhr.open("GET", template, true);
    xhr.send();
}

}
(BASEURL是application.js中定义的全局变量)

一开始一切正常。调用getHomeScreen(),它将设法调用getRemoteJSON()并将_jsonLoaded()作为回调传递。getRemoteJSON执行AJAX调用,然后运行回调。这就是问题所在。一旦在_jsonLoaded内部,“this”将变得未定义,因此当我调用this.getRemoteXMLFile时,会收到错误消息“undefined不是一个对象(评估'this.getRemoteXMLFile')”

为什么“this”在getHomeScreen()中工作,而在jsonLoaded()中不工作?如何从_jsonload()访问getRemoteXMLFile函数


谢谢您的帮助。

这是因为回调不是函数

一个好的解决方案是使用ES6承诺

下面是一个使用AJAX获取数据的示例

getJson(url) {
    return new Promise(
        (resolve, reject) => {
            this.get(url).then(
                (value) => {
                    resolve(JSON.parse(value));
                },
                function (reason) {
                    console.error(reason);
                    reject(new Error(reason));
                }
            )
        }
    )
}
怎么称呼呢

getJson('http://jsonplaceholder.typicode.com/posts/1').then(
    (value) => {
        console.log(value);
    },
    function (reason) {
        console.error(reason);
    }
);
为什么“this”在getHomeScreen()中工作,而在jsonLoaded()中不工作?如何从_jsonload()访问getRemoteXMLFile函数

从技术上讲,这并不是针对TVML应用程序的,而是一个一般的JS问题,所以让我根据JavaScript回答
这个
(不是双关语)

调用
getHomeScreen
时,在对象实例
resourceLoader.getHomeScreen()
上调用它,因此该
上下文将被保留。但是,当您将
\u jsonload
函数作为函数的回调参数传递并执行
回调(模板,xhr.responseText)
时,对象上下文将丢失

最近引入的JavaScript
class
关键字适用于具有纯OOP语言背景的人,因为它不是一种面向对象的继承,而只是JavaScript中古老原型继承的一种语法糖。因此,如果一个人恰好属于同一个群体,那么最好理解他们之间的差异和差异

话虽如此,解决眼前问题的一个简单明了的方法是,每当您将函数作为回调传递时,绑定
这个
上下文

this.getRemoteJSON(homeData, homeTemplate, this._jsonLoaded.bind(this));
旁注:您是否尝试过构建TVML应用程序的框架?它可以让你在没有太多噪音的情况下快速构建和原型化应用程序,抽象出传统TVML应用程序的潜在麻烦和复杂性