您正在正确分配函数(只有一种分配函数的方法),您的问题是函数的上下文发生了变化。
考虑这一行:
this.ws.onopen = this.onOpen;
可能性一:
现在我假设,在 WebSocket
某个地方,这个函数被调用作为对打开连接(如事件处理程序)的响应,可能像
this.onopen();
this
函数内部所指的内容取决于函数在运行时的调用方式(<-
阅读此链接,它有很大帮助)。它在定义时不受约束。在您的情况下,this
将引用该WebSocket
实例。
所以 inside 如果以这种方式调用, insideMyObject.prototype.onOpen
指this
的是没有属性的实例,而不是this.ws
实例。WebSocket
ws
MyObject
这可以通过两种方式解决:
既然this
已经引用了this.ws
,可以send
直接调用this
:
MyObject.prototype.onOpen = function() {
this.send("hello");
};
如果您希望this
insideMyObject.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");
}
可能也会起作用。