【问题标题】:Javascript OO reference thisJavascript OO 参考这个
【发布时间】:2025-11-24 02:25:01
【问题描述】:

简短描述:我正在使用带有函数声明、新关键字和原型方法的 OO Javascript(示例如下)。我需要一种方法来引用对象的每个方法中的“自我”对象。 “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

我尽量简化代码,并在 cmets 中解释问题。我为第一个场景(调用 this.myCallback)创建了一个解决方法,方法是创建 this 的本地副本并使回调参数成为匿名函数,该函数使用我的本地副本调用我需要的函数。但第二种情况更麻烦(事件触发)。

我很好奇是否存在不同的面向对象编程模型,其中每个方法总是对父对象具有正确的引用,而不管方法是如何被调用的?或者如果有不同的方法来创建一个对象作为自定义对象的属性并将其事件绑定到自定义对象的方法?对不起,如果这是令人困惑的语言!请注意,我的问题与 RTCPeerConnection 无关,恰好是我目前正在从事的项目。

我找到了这篇文章:http://www.alistapart.com/articles/getoutbindingsituations,但我不完全确定如何使用这些信息?

【问题讨论】:

    标签: javascript oop


    【解决方案1】:

    我很好奇是否存在不同的面向对象编程模型,其中每个方法总是对父对象具有正确的引用,而不管方法是如何被调用的?

    是的,有:它叫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));
    };
    

    【讨论】:

    • 好的,谢谢!出于某种原因,我只能在提交后从另一个问题中找到答案(它出现在旁边,但没有出现在“可能相关的问题”中)。很抱歉已经回答了问题,但感谢您的回答。
    【解决方案2】:

    方法只是一个定义为原型属性的函数。它本身没有任何特定的对象上下文,这是有原因的,因为给定类型的对象可能有无数个,因此该方法在给定特定对象的上下文时有效。

    在 javascript(以及其他 OO 语言)中,该对象上下文由调用者提供。这样做的经典方法是在特定对象上调用方法:

    obj.method();
    

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

    因此,调用者必须负责确保this ptr 设置正确。这就是javascript的工作原理。

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

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

    在这里,您将this ptr 保存在一个局部变量中,并使用它从匿名回调中调用方法,因为回调中的this 指针将被设置为其他值。

    注意:在内部,.bind() 只是在做与此解决方法类似的事情。

    【讨论】: