Javascript prototypíng 和 this of instantiated object



这是一个棘手的问题。我创建了一个类...

App = function(o) {
    var _app = this;
    this.events = {
        listeners : {
            list : new Array(),
            add : function(event, fn) {
                if (! this.list[event]) this.list[event] = new Array();
                if (!(fn in this.list[event]) && fn instanceof Function) this.list[event].push(fn);
                if (_app.debug.get()) _app.events.dispatch('log.append','EVENTS:ADD:'+event);
            },
            remove : function(event, fn) {
                if (! this.list[event]) return;
                for (var i=0, l=this.list[event].length; i<l; i++) {
                    if (this.list[event][i] === fn) {
                        if (_app.debug.get()) _app.events.dispatch('log.append','EVENTS:REMOVE:'+event);
                        this.list[event].slice(i,1);
                        break;
                    }
                }
            }
        },
        dispatch : function(event, params) {
            if (! this.listeners.list[event]) return;
            for (var i=0, l=this.listeners.list[event].length; i<l; i++) {
                if (_app.debug.get()) _app.events.dispatch('log.append','EVENTS:DISPATCH:'+event);
                this.listeners.list[event][i].call(window, params);
            }
        }
    };
};

并在以后制作更多功能的原型。这是一个;

App.prototype.connection = {
    source : { 'default' : null },
    types : new Array(),
    pool : new Array(),
    count : function() { return this.pool.length },
    active : {
        pool : new Array(),
        count : function() { return this.pool.length },
        add : function(o) { this.pool.push(o) },
        remove : function(o) { this.pool.splice(this.pool.indexOf(o), 1); }
    },
    create : function(o) {
        if (! o || ! o.exe) o.exe = this.source.default;
        if (! o || ! o.type) o.type = 'xhr';
        var c = new this.types[o.type];
        App.events.dispatch('connection.created',c);
        this.pool.push(c);
        return c;
    },
    remove : function(o) {
        App.events.dispatch('connection.removed',o);
        this.pool.splice(this.pool.indexOf(o), 1);
    },
    abort : function(o) {
        var i = this.pool.indexOf(o);
        if (i===-1) return;
        this.pool[i].abort();
    }
};

然后将其实例化为一个对象。

app = new App();

问题是,我有一行名为App.events.dispatch('connection.removed',o)的行不起作用。应用程序需要是实例化"应用程序",理想情况下是"this",但这是指App.prototype.connection。在这种情况下,你如何找到根源?

谢谢 - 安德鲁

您不能使用对象文字方法来定义prototype上的connection,否则无法访问App实例。

请注意,当您引用 App 时,您引用的是构造函数,而不是App实例。此外,例如,create 内部的this将不起作用,因为this将指向connection对象,而不是App实例。

有以下几种选择:

function Connection(eventBus) {
    this.eventBus = eventBus;
}
Connection.prototype = {
    someFunction: function () {
        this.eventBus.dispatch(...);
    }
};
function App() {
    // this.events = ...
    //the instance could also be injected, but you would need to implement
    //a setEventBus on the connection object, or simply do conn.eventBus = this;
    this.connection = new Connection(this);
}
var App = new App();

另外,请注意,prototype上定义的所有可变值(例如对象)将在所有实例之间共享。这可能不是你想要的。

另请注意:

 listeners : {
     list : new Array()

应该是:

 listeners : {
     list : {}

数组应该只有numeric索引,而普通对象是用作映射的更好结构。

最新更新