无法访问Typescript中的对象

时间:2014-04-07 09:37:43

标签: typescript

我无法从函数中访问Typescript中类中声明的对象。这就是我所拥有的:

export class QUestions {

    credentials:mysqlCredentials.MySQLCredentials;
    sqlConnector:mysql.Mysql;

    constructor() {
        this.credentials = new mysqlCredentials.MySQLCredentials('192.168.249.139', 'dev', 'dev', 'test');
        this.sqlConnector = new mysql.Mysql(this.credentials);
    }

    addQuestion(req, res) {
        var q = ...<Lot of code over here> ; 
        this.sqlConnector.query(q, null);  //Error shown for this line
        res.send();
    }
}

Error:
TypeError: Cannot call method 'query' of undefined

如果代码的结构如上所示,即在Typescript类中定义了sqlConnector变量,则会抛出错误。如果我将sqlConnector放在Typescript类之外,它可以正常工作。我需要解决这个问题,因为我需要在类中使用sqlConnector对象。

export class Questions {

    credentials:mysqlCredentials.MySQLCredentials;

    constructor() {
        this.credentials = new mysqlCredentials.MySQLCredentials('192.168.249.139', 'dev', 'dev', 'test');
        sqlConnector = new mysql.Mysql(this.credentials);
    }

    addQuestion(req, res) {
        var q = ...<Lot of code over here> ; 
        sqlConnector.query(q, null);  //Error shown for this line
        res.send();
    }
}

var sqlConnector;

2 个答案:

答案 0 :(得分:1)

您是否在新的上下文中调用该类(例如使用事件处理程序)?

如果是这样,this将成为事件的上下文,而不是类上下文。这也是TypeScript中常见的JavaScript问题。

您可以通过多种方式解决范围问题:

使用箭头功能

如果使用箭头函数将函数分配给Questions类的成员,它将始终使用类作用域。

export class Questions {

    credentials:mysqlCredentials.MySQLCredentials;
    sqlConnector:mysql.Mysql;

    constructor() {
        this.credentials = new mysqlCredentials.MySQLCredentials('192.168.249.139', 'dev', 'dev', 'test');
        this.sqlConnector = new mysql.Mysql(this.credentials);
    }

    addQuestion = (req, res) => {
        var q = ...<Lot of code over here> ; 
        this.sqlConnector.query(q, null);  //Error shown for this line
        res.send();
    }
}

使用call设置范围上下文

此替代解决方案意味着Questions类不需要关注范围 - 如果从不同的范围上下文调用该方法,则只需使用call将问题实例指定为范围。

element.onclick = function () {
    questions.addQuestion.call(questions, argA, argB);
};

答案 1 :(得分:0)

也可以将类实例分配给变量,在编译后它将保留在模块范围内:

var scl:QUestions;
export class QUestions {

    credentials:mysqlCredentials.MySQLCredentials;
    sqlConnector:mysql.Mysql;

    constructor() {
        scl = this;
        this.credentials = new mysqlCredentials.MySQLCredentials('192.168.249.139', 'dev', 'dev', 'test');
        this.sqlConnector = new mysql.Mysql(this.credentials);
    }

    addQuestion(req, res) {
        var q = ...<Lot of code over here> ; 
        scl.sqlConnector.query(q, null); 
        res.send();
    }
}

请注意,如果在单个模块中有许多QUestions类实例,则可能会导致一些问题。在大多数情况下仍然可以正常工作。