2014-01-14 3 views
0

У меня есть объект, основанный на некотором закрытии, и хочу реализовать схему событий здесь:JavaScript События на основе объекта Закрытия

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

В вашем первом блоке кода вы возвращаете объект, который отличается от или self.

В ваших конструкторах необязательно возвращать 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, чтобы создать их для того, чтобы ваши читатели стали более понятными).

+0

Да, конечно. Мэтт, ты совершенно прав! Я каким-то образом почувствовал это решение, но пока не смог найти этот ясный. Большое спасибо! –

Смежные вопросы