JavaScript面向对象参考this

3

简介:我正在使用函数声明、new关键字和原型方法的OO Javascript(下面是示例)。我需要一种方法来引用每个方法中的“self”对象。如果我直接调用该方法,“this”似乎只能起作用,否则“this”似乎会指向调用该方法的任何内容。

更多细节:这是我的对象的简化版本。

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),我通过创建this的本地副本并将回调参数设置为匿名函数来创建了一个解决方法,该匿名函数使用我的本地this副本调用所需的函数。但是第二个场景更麻烦(触发事件)。
我想知道是否有一种不同的面向对象编程模型,其中每个方法始终具有对父对象的正确引用,而不管如何调用该方法?或者是否有一种不同的方式将对象创建为自定义对象的属性并将其事件绑定到自定义对象的方法?如果这很令人困惑,请原谅!请注意,我的问题与RTCPeerConnection无关,那只是我目前正在工作的项目。
我找到了这篇文章:http://www.alistapart.com/articles/getoutbindingsituations,但我不太确定如何使用这些信息?
2个回答

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));
};

是的,谢谢!出于某种原因,在提交问题后,我只能在这里从另一个问题中找到答案(它显示在侧边栏中,但不在“可能相关的问题”中)。对于已经回答的问题,我很抱歉,但感谢您的答案。 - 2bsharpdev

1
一个方法只是在原型上定义为属性的函数。它本身没有任何特定的对象上下文,这是有原因的,因为可以有无限数量的给定类型的对象,所以当给定特定对象的上下文时,该方法才能工作。
在JavaScript(以及其他面向对象的语言中),对象上下文由调用者提供。传统的做法是在特定对象上调用该方法:
obj.method();

但是,您也可以使用 .apply().call().bind()this 指针设置为其他内容。您可以在 MDN 上阅读有关它们的所有信息。.bind() 在一些旧浏览器上不受支持,因此您需要使用 shim 或使用其他解决方案(我使用下面提到的解决方案)。

因此,调用者必须负责确保适当设置 this 指针。这就是 JavaScript 的工作方式。

尝试将方法调用作为回调传递时,另一种设计模式的解决方法如下:

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

在这里,您将this指针保存在本地变量中,并使用它来从匿名回调中调用方法,因为回调中的this指针将被设置为其他内容。

注意:在内部,.bind()只是执行类似于此解决方法的操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接