Установка C.prototype.constructor = C приводит к Stackru
Я изучал наследование js и в качестве учебного проекта я создаю собственную реализацию наследования базового класса. extend
метод для создания новых классов. я использую C.prototype.constructor = C
как говорит Стоян Сефанов, это приводит к переполнению стека, когда я пытаюсь вызвать конструктор базового класса.
Проблема в том, что второй уровень наследования продолжает вызывать свой собственный конструктор! Если я уберу эту строку, мое наследование, похоже, будет работать нормально.
Вот моя реализация кода базового класса.
(function(TestFramework, undefined) {
TestFramework.Class = function() {};
TestFramework.Class.extend = function(ctor) {
var base = this;
var derived = ctor;
//Duplicate static property access to derived
for (var property in base) {
if (base.hasOwnProperty(property)) derived[property] = base[property];
}
//Create lightweight intermediate constructor to avoid calling the base constructor
function lightweightCtor() { this.constructor = derived; };
//Setup prototype chain
lightweightCtor.prototype = base.prototype;
derived.prototype = new lightweightCtor();
derived.prototype._MyBase = lightweightCtor.prototype;
derived.prototype._MyBaseCtor = function() {
base.prototype.constructor.apply(this, arguments);
};
//Return derived class
return derived;
};
TestFramework.Class.prototype.ClassName = "TestFramework.Class";
})(window.TestFramework);
2 ответа
Я провел немного времени, глядя на скрипку. Я не совсем уверен, что вы намереваетесь сделать код, но в строке 23 у вас есть:
base.prototype.constructor.apply(this, arguments);
который вызывает линию 35..
this._MyBaseCtor();
.. который вызывает линию 23, которая вызывает линию 35 и т. д.
Два предложения (простите, если вы хорошо знаете). Используйте оператор отладчика при отладке - обязательно. Рассмотрим библиотеку, например Underscore.js, если вы хотите использовать проверенное наследование в производственной среде.
Теперь, когда я понял проблему, решение было довольно простым. Я просто должен был сохранить ссылку на оригинальный ctor, прежде чем перезаписывать его, и вызывать его изнутри _MyBaseCtor
, Вот обновленная скрипка.
Во-первых, удалите переопределение конструктора внутри определения lightweightCtor.
//Create lightweight intermediate constructor to avoid calling the base constructor
function lightweightCtor() {};
Затем добавьте новый раздел для настройки конструктора. Обратите внимание на проверку, если base.__BaseCtor
настроен и использует по умолчанию base.prototype.constructor
если это не так.
//Setup constructor references
derived.__BaseCtor = base.__BaseCtor || base.prototype.constructor;
derived.prototype.constructor = derived;
derived.prototype._MyBaseCtor = function() {
derived.__BaseCtor.apply(this, arguments);
};