【问题标题】:JavaScript Event implementation to Closure based Object基于闭包的对象的 JavaScript 事件实现
【发布时间】:2014-01-14 08:04:21
【问题描述】:

我有一个基于闭包的对象,想在这里实现事件方案:

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。

感谢您的建议。

【问题讨论】:

    标签: javascript closures


    【解决方案1】:

    在您的第一个代码块中,您将返回一个与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 实例化它们以使您的读者更清楚)。

    【讨论】:

    • 是的,当然。马特,你完全正确!我不知何故感觉到了这个解决方案,但到目前为止还没有找到这个明确的解决方案。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    相关资源
    最近更新 更多