2013-01-11 77 views
3

簡短的描述:我正在使用函數聲明,新的關鍵字和原型方法(下面的例子)的OO Javascript。我需要一種方法來引用對象的每個方法中的「自我」對象。 「this」似乎只在我直接調用方法時才起作用,否則「this」似乎是指所謂的方法。Javascript OO參考這個

更多細節:這是我的對象的簡化版本。

function Peer(id) { 
    this.id = id; 
    this.pc = new RTCPeerConnection(SERVER); 

    this.pc.onevent1 = this.onEvent1; 
    this.pc.onevent2 = this.onEvent2; 
} 

Peer.prototype.doSomething = function() { 
    // create offer takes one param, a callback function 
    this.pc.createOffer(this.myCallback); 
}; 

Peer.prototype.onEvent1 = function(evt) { 
    // here this refers to the RTCPeerConnection object, so this doesn't work 
    this.initSomething(evt.data);  
}; 

Peer.prototype.myCallback = function(data) { 
    // here this refers to the window object, so this doesn't work 
    this.setSomething = data; 
}; 

Peer.prototype.initSomething = function(data) { 
    // use data 
}; 

這裏是它的一個示例使用。

var peer = new Peer(1); 
peer.doSomething(); 
// eventually something triggers event1 

我試圖儘可能簡化代碼並在註釋中解釋問題。我爲第一個場景創建了一個解決方法(調用this.myCallback),方法是創建一個本地副本並使回調參數成爲使用本地副本調用我需要的函數的匿名函數。但第二種情況更麻煩(事件發生)。

我很好奇,如果面向對象編程有一個不同的模型,其中每個方法總是有一個適當的父對象引用,而不管該方法是如何被調用的?或者,如果有不同的方式將對象創建爲自定義對象的屬性並將其事件綁定到自定義對象的方法?對不起,如果這是混淆語言!請注意,我的問題與RTCPeerConnection無關,只是恰好是我正在處理的項目。

我發現這篇文章:http://www.alistapart.com/articles/getoutbindingsituations但我不完全知道如何使用這些信息?

回答

6

我很好奇,如果面向對象的編程有一個不同的模型,其中每個方法總是有一個適當的父對象引用,不管該方法如何被調用?

是的,有:它叫做Function.bind

function Peer(id) { 
    this.id = id; 
    this.pc = new RTCPeerConnection(SERVER); 

    this.pc.onevent1 = this.onEvent1.bind(this); 
    this.pc.onevent2 = this.onEvent2.bind(this); 
} 

同樣地,對於myCallbackthis總是引用Peer實例:

Peer.prototype.doSomething = function() { 
    // create offer takes one param, a callback function 
    this.pc.createOffer(this.myCallback.bind(this)); 
}; 
+0

是的,謝謝!出於某種原因,我只能在提交後從另一個問題找到答案(它出現在旁邊,但不是在「可能相關的問題」中)。對不起,已經回答的問題,但謝謝你的答案。 – 2bsharpdev

1

的方法僅僅是真實定義爲在一個原型的性質的函數。它本身沒有任何特定的對象上下文,這是出於某種原因,因爲可以有無限數量的給定類型的對象,因此該方法在給定特定對象的上下文時工作。

在JavaScript(以及其他OO語言)中,該對象上下文由調用者提供。這樣做的經典的方式是你調用特定對象的方法:

obj.method(); 

但是,你也可能會導致使用.apply().call().bind()this指針設置爲別的東西。你可以在MDN上閱讀它們的全部內容。某些舊瀏覽器不支持.bind(),因此您需要使用墊片或使用其他解決方案(我使用下面提到的解決方案)。

因此,來電者必須承擔責任,確保this ptr設置適當。這就是javascript的工作原理。

另一種設計模式的變通試圖通過方法調用的回調是這樣的,當:

var self = this; 
callMeWhenDone(function() { 
    self.myMethod(); 
}); 

在這裏,你保存this PTR在一個局部變量,並用它來調用從方法一個匿名回調,因爲回調中的指針this將被設置爲別的。

注意:在內部,.bind()正在做類似於此解決方法的操作。