在函数内使用“this” - nodeJS

时间:2013-11-18 11:13:07

标签: javascript node.js oop scope

我正在尝试在node.js中为我的一个小项目创建一个类,但我无法弄清楚范围是如何工作的。

我有一个基本的构造函数:

function testClass(username){
this.config = {
    uName : username,
    url : 'url_prefix'+username,
};

this.lastGame = {
    firstTime : 1,
    time : null,
    outcome: null,
    playingAs: null,
    playingAgainst : null,
    };

this.loadProfile(this.config['url']);
}; 

loadProfile函数:

testClass.prototype.loadProfile = function(url){

    request(url,function(error,response,body){

        $ = cheerio.load(body);
        matchTable = $('div[class=test]').children();
        tempLast = matchTable.first().html();

        if(this.config['firstTime'] == 1 || this.lastGame['time'] != tempLast){
            this.lastGame['time'] = tempLast;
        }


    });
};

(我正在使用Request和Cheerio库。)

我遇到的问题是我无法在“请求”功能中使用“this”来使用类变量 它返回“无法读取未定义的属性'firstTime'。” 这只发生在“请求”功能中。我可以使用“this”及其所有函数/变量就好了。
我已经考虑过将它传递给函数但是a)我找不到如何和b)这意味着我对变量所做的任何修改都不会改变实际的类变量。
有人可以解释一下发生了什么吗? 非常感谢!

3 个答案:

答案 0 :(得分:1)

每个function都会创建一个新范围,因为范围在JavaScript中以函数为中心。 ES6 let keyword将帮助您规避这种情况。在此之前,您必须坚持保留对您要使用的this的引用。

testClass.prototype.loadProfile = function(url){
    var self = this;

    request(url,function(error,response,body){

        $ = cheerio.load(body);
        matchTable = $('div[class=test]').children();
        tempLast = matchTable.first().html();

        if(self.config['firstTime'] == 1 || self.lastGame['time'] != tempLast){
            self.lastGame['time'] = tempLast;
        }


    });
};

更新

  

如果我设置self.config['time'] = "whatever",则this.config['time']保持不变。

是。这是因为this引用了request函数的本地范围,而不是您要引用的loadProfile范围。这就是您应该使用self引用而不是this的原因。 selfthis的上下文中提到loadProfile。然后,当您输入this回调的上下文时,request已更改。

答案 1 :(得分:1)

典型的解决方案是将this复制到另一个名为self的变量中。

但是,如果您不打算创建很多“类”实例,或者它只有一些方法,那么通常更容易避免使用构造函数this和{{1一共。

new

这使您可以拥有真正的私人数据,而且您不必手动复制function makeAnObject(username){ // declare private information: var url = 'url_prefix' + username; // return public information (usually functions): return { loadProfile: function(blah) { // ... } }; }; 的参数,也不必担心makeOnObject被破坏,或者记住使用this等进行前缀调用

答案 2 :(得分:0)

内部请求你有不同的范围。 内部请求函数可能是请求对象的实例。你可以尝试类似的东西:

testClass.prototype.loadProfile = function(url){
    var self = this;

    request(url,function(error,response,body){
        $ = cheerio.load(body);
        matchTable = $('div[class=test]').children();
        tempLast = matchTable.first().html();

        if(self.config['firstTime'] == 1 || self.lastGame['time'] != tempLast){
            self.lastGame['time'] = tempLast;
        }


    });
};