您正在正确分配函数(只有一种分配函数的方法),您的问题是函数的上下文发生了变化。
考虑这一行:
this.ws.onopen = this.onOpen;
可能性一:
现在我假设,在 WebSocket某个地方,这个函数被调用作为对打开连接(如事件处理程序)的响应,可能像
this.onopen();
this函数内部所指的内容取决于函数在运行时的调用方式(<-阅读此链接,它有很大帮助)。它在定义时不受约束。在您的情况下,this将引用该WebSocket实例。
所以 inside 如果以这种方式调用, insideMyObject.prototype.onOpen指this的是没有属性的实例,而不是this.ws实例。WebSocketwsMyObject
这可以通过两种方式解决:
既然this已经引用了this.ws,可以send直接调用this:
MyObject.prototype.onOpen = function() {
this.send("hello");
};
如果您希望thisinsideMyObject.prototype.onOpen始终引用MyObject实例,则必须保持对实例的显式引用,例如通过闭包:
var self = this;
this.ws.onopen = function() {
self.onOpen();
};
现在里面onOpen,this指的是MyObject具有属性的实例ws,就像你在构造函数中设置它一样。
在支持 ECMAScript 5 的浏览器中,函数已经有了这种技术的方法,称为.bind():
this.ws.onopen = this.onOpen.bind(this);
可能性2:
也可能是这样WebSocket调用onopen的:
this.onopen.call(null);
在这种情况下,this将引用window或将是undefined,取决于代码是否在严格模式下运行(没关系,无论如何这是一个问题)。
这种情况只能通过第一种可能性的第二种解决方案来解决。
为什么第一个示例有效?
var ws = new WebSocket(something, somethingelse);
ws.onopen = function() {
ws.send("hello");
console.log("works");
}
在这种情况下,您分配给的函数ws.onopen是一个闭包,关闭在此范围内定义的变量,也是ws. 从这个意义上说,它类似于解决问题的第二种方法,但
ws.onopen = function() {
this.send("hello");
console.log("works");
}
可能也会起作用。