I use typescript with the reference "atmosphere.d.ts" source here . I trigged a strange behaviour with abstract methods which leads to the error :
TypeError: this.protectedMethod is not a function
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 :
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. 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. Is there an explanation to this behaviour, and a workaround/fix? Btw, I use typescript 1.8.10
Thanks,
This is due to 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;
}());
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).
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.socket.onOpen = response => {
this.protectedMethod();
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.