2013-09-27 37 views
0

中我有一个类Gadget一个方法consider定义为:调用类方法的WebSocket对象

function Gadget() { 

    this.consider = function (arg) { 
     alert(arg); 
    }; 

    if ("WebSocket" in window) { 
     var ws = new WebSocket(...); 
     // the rest truncated 

     ws.onmessage = function (evt) { 
      consider(evt.data); 
     }; 
    } 
} 

我,但是,无法得到consider的工作,因为它没有一个TypeError

Uncaught TypeError: Object #<Gadget> has no method 'consider' 

如果我尝试使用this.consider相反,TypeError发生与的WebSocket对象。如果我尝试parent.consider,那么对象对象给我提供了同样的错误。

现在我的解决方法是使用从声明的实例方法,如:

var player = new Gadget(); 

player.consider(evt.data)代替。我不喜欢这样做,但它有效。我如何重新排列代码,使其不依赖于对象的已定义实例?

+0

'var self = this; ws.onmessage = function(evt){self.consider(evt.data);};' – Passerby

+0

这会让它在函数内可访问,我猜?嗯,谢谢! – icedwater

回答

2

有两种方法可以解决这个问题。

1)使用私有函数

function Gadget() { 

    function consider(arg){ 
     alert(arg); 
    } 

    this.consider = consider; 

    if ("WebSocket" in window) { 
     var ws = new WebSocket(...); 
     // the rest truncated 

     ws.onmessage = function (evt) { 
      consider(evt.data); 
     }; 
    } 
} 

这种方式,你有你的Gadget类中的私有consider()功能,即使它的实例锻炼自己的consider方法(如var x=new Gadget(); x.consider=...),网络套接字仍然按照你的意图工作;

2) “高速缓存” this

function Gadget() { 
    this.consider = function(arg){ 
     alert(arg); 
    }; 

    if ("WebSocket" in window) { 
     var ws = new WebSocket(...); 
     // the rest truncated 

     var self=this; 
     ws.onmessage = function (evt) { 
      self.consider(evt.data); 
     }; 
    } 
} 

这样你的web套接字事件总是会使用任何小工具的实例想consider是。

Here is a jsfiddle demo这证明了这两种方式。请注意,我有意地锻炼了(第二个按钮)的实例的consider方法。点击这些按钮可以看到不同的。

+0

我在之前的评论中使用了第二种解决方案的变体。我只是在'if'块中声明'var self = this;'。谢谢! – icedwater

+1

@icedwater哎呀,我的坏。我的意思是把'var self = this'放在'if'里面,但是因为我的小提琴中没有'if',所以我只是部分地复制了你的问题的代码,而没有付出太多的关注。 – Passerby