2013-01-11 63 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()正在做类似于此解决方法的操作。