基于Closure的Object的JavaScript事件实现

时间:2014-01-14 08:04:21

标签: javascript closures

我有一个基于某些闭包的Object,并希望在这里实现事件方案:

var class1 = function(val1)
{
    var val = val1;    
//------ want to call a method of Object of class1--------
    var self = this;
    setTimeout(function()
    {
        self.onEvent();

    }, 1000);
//----------------  
    return {
        f1: function()
        {
            return val;
        },
        onEvent: function()
        {
            console.log('not implemented yet. Override');
        }
    };
};

var obj1 = class1(5);
console.log(obj1.f1()); //5

obj1.onEvent(); //not implemented yet. Override   
obj1.onEvent = function()
{
    console.log('event fired');
}

得到错误,我知道原因,我需要一个解决方案:

5
not implemented yet. Override

/....../app.js:9
        self.onEvent();
             ^
TypeError: Object #<Object> has no method 'onEvent'

如果这与addEventListener方案绑定可能是这样的:

(这个想法基于 Implementing events in my own object

var class2 = function()
{
    var _this = this;
    _this.events = {};
    var fireEvent = function(name, args)
    {
        if (!_this.events.hasOwnProperty(name)) return;
        if (!args || !args.length) args = [];  
        var evs = _this.events[name];
        var l = evs.length;
        for (var i = 0; i < l; i++)
        {
            evs[i].apply(null, args);
        }
    };   
    setTimeout(function()
    {
        fireEvent('testEvent', ['hello'])
    }, 1000);   
    return {
        addEventListener: function(name, handler)
        {
            if (_this.events.hasOwnProperty(name))
                _this.events[name].push(handler);
            else
                _this.events[name] = [handler];
        }
    };
};  
var obj2 = class2();   
obj2.addEventListener('testEvent',
    function(data)
    {
        console.log('event fired: ' + data);
    });

event fired: hello

但是,我不想使用addEventListener而是使用.onEvent()方案。

有可能吗?也许可以使用call / apply。

感谢您的建议。

1 个答案:

答案 0 :(得分:0)

在第一个代码块中,您将返回一个与thisself不同的对象。

您不一定要在构造函数中返回this,但是您应该在返回的对象上分配函数。如果您为要返回的对象创建变量,则可以在setTimeout回调中使用它,如下所示:

var class1 = function(val1)
{
    var val = val1;    

    var obj = {
        f1: function()
        {
            return val;
        },
        onEvent: function()
        {
            console.log('not implemented yet. Override');
        }
    };

    setTimeout(function()
    {
        obj.onEvent();

    }, 1000);

    return obj;
};

对于额外的样式点,您可能希望将构造函数的名称大写(并且可能使用new来实例化它们以使读者更清楚。)