JavaScript Event implementation to Closure based O

2020-05-06 11:05发布

I have a Object based on some closure, and want to implement event scheme here:

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

got error, and I know the reason, and I need a solution:

5
not implemented yet. Override

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

It is possible if this bind with addEventListener scheme like this:

(The idea based on 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

However, I prefer not to use addEventListener but .onEvent() scheme.

Is it possible? Perhaps it is possible using call/apply.

Thanks for your advice.

1条回答
劳资没心,怎么记你
2楼-- · 2020-05-06 11:21

In your first block of code, you are returning an object, which is different from this or self.

You don't necessarily have to return this in your constructors but you should assign your functions on the returned object. If you create a variable for the object you want to return, you can use it in your setTimeout callback like so:

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

For extra style points, you might want to capitalize the name of your constructors (and perhaps use new to instantiate them to make things clearer to your readers).

查看更多
登录 后发表回答