简体   繁体   English

抽象方法TypeScript的怪异行为

[英]Weird behaviour with abstract method TypeScript

I use typescript with the reference "atmosphere.d.ts" source here . 在此处将打字稿与参考“ atmosphere.d.ts” 源一起使用 I trigged a strange behaviour with abstract methods which leads to the error : 我用抽象方法触发了一个奇怪的行为,这导致了错误:

TypeError: this.protectedMethod is not a function TypeError:this.protectedMethod不是函数

Here is the typescript code : 这是打字稿代码:

/// <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");
    }
}

Without error, the folllowing javascript code is generated : 没有错误,将生成以下javascript代码:

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

I can't call the abstract method (may be non abstract either?) from the "socket" variable when I implement the "onOpen" method. 实现“ onOpen”方法时,无法从“ socket”变量调用抽象方法(也可能是非抽象方法)。 The only workaround I found for now, is to instantiate a global variable 我现在发现的唯一解决方法是实例化全局变量

var registration = new Registration();

and then : 接着 :

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

With this workaround, I have to define "protectedMethod" public. 通过这种解决方法,我必须定义“ protectedMethod”公共。 Is there an explanation to this behaviour, and a workaround/fix? 是否有对此行为的解释以及解决方法/修复程序? Btw, I use typescript 1.8.10 顺便说一句,我使用打字稿1.8.10

Thanks, 谢谢,

This is due to the way that this works in JavaScript : 这是由于该方式this工作在JavaScript

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

When you call new AbstractRequest().socket.onOpen() this will be bound to socket not to new AbstractRequest() ( this points to whatever is on the left of the dot). 当你调用new AbstractRequest().socket.onOpen() this将被绑定到socketnew AbstractRequest() this指向无论是在点的左边)。

You can use an arrow function to work around this. 您可以使用箭头功能来解决此问题。 Within arrow functions this is bound to the context it was defined in, not the context it is being run in: 在箭头的功能this势必会有人在,没有它正在被运行的背景下定义的上下文:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM