使用抽象方法TypeScript的奇怪行为

时间:2016-07-21 20:07:29

标签: javascript typescript

我使用typescript作为参考" atmosphere.d.ts" https://api.jquery.com/jquery.deferred/。我用抽象方法触发了一个奇怪的行为,导致错误:

  

TypeError:this.protectedMethod不是函数

以下是打字稿代码:

Region      A   B   C   Special Count
Region 1    1   0   1   1
Region 2    1   2   0   0
Region 3    0   1   1   1

没有错误,会生成以下javascript代码:

/// <reference path="../atmosphere.d.ts" />
import Request = Atmosphere.Request;

abstract class AbstractRequest {

    // The atmosphere request
    protected socket: Request;

    // Here we initialize the socket
    protected init(url: string): void {
        this.socket = {
            url                 : "http://localhost:9000/" + url,
            contentType         : "application/json",
            transport           : "websocket" ,
            fallbackTransport   : "long-polling"
        };

        /* SOME CODE */

        this.socket.onOpen = function(response) {
            this.protectedMethod();
        };
    }

    // Some protected method called in this.socket.onOpen
    protected abstract protectedMethod(): void;
}

class Registration extends AbstractRequest {

    // Implementation of the abstract method
    protected protectedMethod(): void {
        console.log("hello");
    }
}

我不能从&#34; socket&#34;中调用抽象方法(也可能是非抽象的?)当我实现&#34; onOpen&#34;方法。我现在发现的唯一解决方法是实例化一个全局变量

var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var AbstractRequest = (function () {
    function AbstractRequest() {
    }
    // Here we initialize the socket
    AbstractRequest.prototype.init = function (url) {
        this.socket = {
            url: "http://localhost:9000/" + url,
            contentType: "application/json",
            transport: "websocket",
            fallbackTransport: "long-polling"
        };
        /* SOME CODE */
        this.socket.onOpen = function (response) {
            this.protectedMethod();
        };
    };
    return AbstractRequest;
}());
var Registration = (function (_super) {
    __extends(Registration, _super);
    function Registration() {
        _super.apply(this, arguments);
    }
    // Implementation of the abstract method
    Registration.prototype.protectedMethod = function () {
        console.log("hello");
    };
    return Registration;
}(AbstractRequest));
//# sourceMappingURL=test.js.map

然后:

var registration = new Registration();

通过这种解决方法,我必须定义&#34; protectedMethod&#34;上市。是否有解释此行为,以及解决方法/修复?顺便说一句,我使用的是typescript 1.8.10

谢谢,

1 个答案:

答案 0 :(得分:4)

这是由于the way that this works in JavaScript

var AbstractRequest = (function () {
    function AbstractRequest() { }
    AbstractRequest.prototype.init = function (url) {
        // ...snip...
        this.socket.onOpen = function (response) {
            this.protectedMethod();
        };
    };
    return AbstractRequest;
}());

当您致电new AbstractRequest().socket.onOpen()时,this将被绑定到socket而不是new AbstractRequest()this指向点左侧的任何内容)。

您可以使用箭头功能解决此问题。在箭头函数中,this绑定到它所定义的上下文,而不是它正在运行的上下文:

this.socket.onOpen = response => {
    this.protectedMethod();
};