Javascript. Простий Observer.

Завдання - зв'язати 2 абсолютно будь-які об'єкти. Не можна змінювати початковий код об'єктів.

Описане нижче розраховане на самостійність читача і бажання розібратися в реалізації.

Приклад (утрований).

Є 2 об'єкти в будинку:

<div id=""a1"" onclick=""alert(123)""></div>
<div id=""a2""></div>

І 1 яваскриптовий:

Core = function() {
 this.some = function(a,b,c,d,e,f,g) {
  var a1 = $('a1').innerHTML
  var a2 = a+''+b+''+c+''+d+''+e+''+f+''+g
  $('a1').innerHTML = a1 + a2
 }
 this.another = function() {
  var a = $('a1').innerHTML
  var a2 = 'some_text_more'
  $('a1').innerHTML = a + a2
 }
 this.another2 = function() {
  var a = $('a2').innerHTML
  var a2 = 'yahoo'
  $('a2').innerHTML = a + a2
 }
}
var Core = new Core()

Потрібно: відреагувати на a1.onclick викликом Core.another2

Реалізація:

var n = Observer.Attach($('a1'), 'onclick', Core, 'another')

Прибираємо Observer:

Observer.Dettach($('a1'), n)

Observer.

Реалізація побудована на клонуванні методу відстежуваного об'єкта.

Observer.Attach клонує метод, створюючи новий з унікальним ім'ям.

Відстежуваному методу присвоюється нова дія, що містить виклик клону і виклик необхідної функції (obj2.call_back)

Черговість виклику контролюємо параметром before методу Observer.Attach.

Observer = function() {}

Observer.prototype = {

 List: {},

 Attach: function(obj, method, obj2, call_back, before) {
  var new_method = this. CloneOldMethod(obj, method)
  eval('obj.'+method+' = '+this.NewDefaultMethod('obj2', call_back, new_method, before))
  return new_method
 },

 Dettach: function(obj, observed_method) {
  eval('var m = this. List.'+observed_method)
  eval('obj.'+m.method+' = m.realization')
  eval('delete(obj.'+observed_method+')')
  eval('delete(this.List.'+observed_method+')')
 },

 NewDefaultMethod: function(obj_name, call_back, new_method, before) {
  var m_old = 'this.'+new_method+'(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6])'
  var m_new = obj_name+'.'+call_back+'()'
  var cmd = ''
  cmd += 'function() {'
  before === true ? cmd += m_new +';'+ m_old : cmd += m_old +';'+ m_new
  cmd += '}'
  return cmd
 },

 CloneOldMethod: function(obj, method) {
  var new_method = 'a'+this.giveUnique()
  eval('obj.'+new_method+' = obj.'+method)
  eval('this.List.'+new_method+' = {object: obj, \'method\': method, realization:obj.'+method+'}')
  return new_method
 },

 giveUnique: function () {
  return (new Date()).getTime()
 }
}
Observer = new Observer()