1

我有一个类Gadget,其中一个方法consider定义为:

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,那么Object对象会给我同样的错误。

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

var player = new Gadget();

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

4

1 回答 1

3

有两种方法可以克服这个问题。

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

这样你的类中就有了一个私有consider()函数Gadget,即使它的实例调整了它自己的consider方法(例如var x=new Gadget(); x.consider=...),web socket 仍然可以按照你的预期工作;

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 套接字事件将始终使用Gadget想要的任何实例consider

这是一个演示这两种方式的 jsfiddle 演示。请注意,我特意调整了(第二个按钮)实例consider的方法。单击这些按钮以查看不同之处。Gadget2

于 2013-09-27T10:03:11.683 回答