2016-12-11 1 views
0

У меня есть класс designMain, который расширяет design.Наследование Javascript с помощью eventListener

Я обнаружил, что если я установить EventListener в design, когда событие вызывается, все ссылки на this будут относиться только к Неправительственному расширенному design объекту. Есть ли способ преодолеть этот недостаток моего расширенного класса?

UPDATE - Я включил версию ES6, которая работает, как ожидалось, и показывает, что я пытаюсь сделать - а именно, что this с расширенными классами всегда будет ссылаться на расширенном классе даже с кодом (например, addEventListener) в пределах базовый класс. В этом случае this.name всегда должен быть из расширенного класса.

Вот a jsFiddle

HTML

<div id="test"> 
    Design (click will fail) 
</div> 

<div id="test2"> 
    DesignMain (click will succeed) 
</div> 

Javascript

design = (function() { 
    function design() { 
    this.name = "design"; 

    var _this = this; 
    var e = document.getElementById("test"); 
    e.addEventListener("click", function() { 
     _this.callHello(); 
    }); 
    } 

    design.prototype.callHello = function() { 
    // I expect that this.name will be "designMain" 
    console.log(this.name) 
    // will fail if called from the design class eventListener 
    this.hello(); 
    } 

    return design; 
})(); 


designMain = (function() { 
    function designMain() { 
    this.name = "designMain"; 
    this.init(); 
    } 

    designMain.prototype.init = function() { 
    this.extend(); 
    var _this = this; 
    var e = document.getElementById("test2"); 
    e.addEventListener("click", function() { 
     _this.callHello(); 
    }); 
    } 

    designMain.prototype.extend = function() { 
    var old = new design(); 
    // save reference to original methods 
    this._designMain = Object.create(old); 
    for (var name in this._designMain) { 
     if (!this[name]) { 
     this[name] = this._designMain[name] 
     } 
    } 
    } 

    designMain.prototype.hello = function() { 
    alert("Hello " + this.name); 
    } 

    return designMain; 
})(); 


var t = new designMain(); 

Использование ES6 - это работает, как ожидалось (see fiddle)

class design { 
    constructor() { 
    this.name = "design"; 

    var _this = this; 
    var e = document.getElementById("test"); 
    e.addEventListener("click", function() { 
     _this.callHello(); 
    }); 
    }; 

    callHello() { 
    // should be "designMain" 
    console.log(this.name) 
    this.hello(); 
    } 

    get name() { 
    return this._name; 
    }; 
    set name(name) { 
    this._name = name; 
    }; 
} 


class designMain extends design { 
    constructor() { 
    super(); 
    this.name = "designMain"; 
    var _this = this; 
    var e = document.getElementById("test2"); 
    e.addEventListener("click", function() { 
     _this.callHello(); 
    }); 
    }; 

    hello() { 
    alert("Hello " + this.name); 
    } 

} 

t = new designMain(); 
+0

Я не понимаю. Вы хотите, чтобы 'design' наследовал от' designMain'? Если да, почему вы ничего не сделали для этого? И что должен делать этот метод 'extend'? – Bergi

+0

Ваш метод 'ceate' (который должен быть статическим, btw) устарел. Вместо этого используйте 'Object.create'. – Bergi

+0

@Bergi - Я обновил вопрос с версией ES6, которая ведет себя так, как ожидалось, а именно, что designMain наследует расширение дизайна, и все ссылки на 'this' будут методами и свойствами DesignMain. Я обновил свой код, чтобы использовать Object.create, и работал со статическими функциями, но не смог получить 'this' для обновления внутри кода, сгенерированного базовым классом. Можно ли моделировать истинное наследование классов без использования класса ES6 Class? – mseifert

ответ

0

Благодаря Берги и ссылке, которую он опубликовал - у меня есть решение. Расширение/наследование было проще с использованием Object.create, и мне нужно было добавить design.call(this) для запуска конструктора базового класса.

designMain = (function() { 
    designMain.prototype = Object.create(design.prototype); 

    function designMain() { 
    design.call(this) 

Рабочий раствор:

design = (function() { 
    function design() { 
    this.name = "design"; 

    var _this = this; 
    var e = document.getElementById("test"); 
    e.addEventListener("click", function() { 
     _this.callHello(); 
    }); 
    } 

    design.prototype.callHello = function() { 
    // will fail if called from the design class eventListener 
    console.log(this.name) 
    this.hello(); 
    } 

    return design; 
})(); 


designMain = (function() { 
    designMain.prototype = Object.create(design.prototype); 

    function designMain() { 
    design.call(this) 
    this.name = "designMain"; 
    this.init(); 
    } 

    designMain.prototype.init = function() { 
    var _this = this; 
    var e = document.getElementById("test2"); 
    e.addEventListener("click", function() { 
     _this.callHello(); 
    }); 
    } 

    designMain.prototype.hello = function() { 
    alert("Hello " + this.name); 
    } 

    return designMain; 
})(); 


var t = new designMain();