2016-08-24 2 views
0

Я думал, что хорошо понимаю, как правильно расширять классы в JavaScript, но при расширении подкласса я запускаю бесконечный цикл, когда переопределяю метод, и вызов родительского метода из дочернего класса. Я либо делаю это неправильно, либо просто не должен подкласса в JavaScript.Как правильно подклассы подкласса в JavaScript?

Может ли кто-нибудь помочь воспитывать меня, пожалуйста?

var Grand = function() { 
 
\t this.test(); 
 
}; 
 

 
Grand.prototype.constructor = Grand; 
 

 
Grand.prototype.test = function() { 
 
\t console.log("Grand!") 
 
}; 
 

 

 

 
var Parent = function() { 
 
    this.supr.constructor.call(this); 
 
}; 
 

 
Parent.prototype = Object.create(Grand.prototype); 
 
Parent.prototype.constructor = Parent; 
 
Parent.prototype.supr = Grand.prototype; 
 

 
Parent.prototype.test = function() { 
 
\t this.supr.test.call(this); 
 
    console.log("Parent!"); 
 
}; 
 

 

 

 
var Child = function() { 
 
    this.supr.constructor.call(this); 
 
}; 
 

 
Child.prototype = Object.create(Parent.prototype); 
 
Child.prototype.constructor = Child; 
 
Child.prototype.supr = Parent.prototype; 
 

 
Child.prototype.test = function() { 
 
\t this.supr.test.call(this); 
 
    console.log("Child!"); 
 
}; 
 

 

 

 
var g = new Grand(); // Outputs "Grand!" 
 
var p = new Parent(); // Outputs "Grand!" "Parent!" 
 
var c = new Child(); // Error: Endless Loop!

я ожидал бы консоль для входа "Гранд!", "Родитель!", "Ребенок!" когда создается экземпляр нового Child(), но вместо этого я получаю бесконечный цикл.

Я исхожу из фона ActionScript, поэтому создание классов в JavaScript по-прежнему бросает мне несколько кривых шаров. Спасибо за помощь в продвижении!

+1

Там нет действительно понятие класса и подкласса JavaScript (кроме синтаксиса сахара в ES6). JavaScript - это прототип базы. – GibboK

ответ

0

Проблема с этим битом кода:

var Parent = function() { this.supr.constructor.call(this);
};

Рассмотрим, что происходит, когда этот код выполняется:

var c = new Child();

Здесь this переменная c, так this.supr.constructor будет всегда быть конструктором родителя в качестве установки в этих строках кода:

Child.prototype.supr = Parent.prototype; // i.e. this.supr = Parent.prototype 
Parent.prototype.constructor = Parent; // i.e. this.supr.constructor = Parent 

Так что, когда конструктор ребенка вызывает this.supr.constructor.call(this); он выполняет функцию Parent, и родительская функция снова выполняет this.supr.constructor.call(this); результате функцию Parent быть вызвано снова, вызывая бесконечный цикл.

Исправление является для вызова функции базового класса следующим образом:

var Child = function() { Child.prototype.supr.constructor.call(this); };

Подробнее в this post

+0

Мне нужно опустить голову, но это имеет смысл. Благодаря! – SpaceCowboy2071

1

Я рекомендую переключение на ES6. Это прототипирование может быть настоящим беспорядком и сложнее отслеживать. Но тогда, если вам это нужно в браузере, вы должны перевести свой код на es5 whit babel или такой. В узле Env его штраф не до тех пор, пока у вас есть последняя обновленная версия. Некоторые из последней версии браузера поддерживает его, а

class Grand { 
 
    constructor() { 
 
     this.test() 
 
    } 
 

 
    test() { 
 
     console.log("Grand!") 
 
    } 
 
} 
 

 
class Parent extends Grand { 
 
    test() { 
 
     super.test() 
 
     console.log("Parent!") 
 
    } 
 
} 
 

 
class Child extends Parent { 
 
    test() { 
 
     super.test() 
 
     console.log("Child!") 
 
    } 
 
} 
 

 
let g = new Grand(); // Outputs "Grand!" 
 
let p = new Parent(); // Outputs "Grand!" "Parent!" 
 
let c = new Child(); // Outputs "Grand!" "Parent! "child!"

Это не только более читаемым, но меньше кода и более понятным

+0

Честно говоря, я предпочел бы пойти с ES6, а не изучать TypeScript или Dart. Я не слишком хорошо знаком с Вавилоном, разве он проверен на бой и достаточно прочен, чтобы я мог зависеть от него для проектов клиентов? Благодаря! – SpaceCowboy2071

+0

Вавилон такой же твердый, как и он. И, пожалуйста, не используйте код на другом языке, который преобразуется в javascript, например, Dart или coffescript.coffescript - самая любимая ненависть в Интернете. – Endless

+1

Если код не может быть выполнен в любой среде браузера/узла, тогда не используйте его, потому что в конце он будет поддерживать то, что пытался выполнить какой-то подготовленный язык. Им также нужно идти в ногу с новейшей версией javascript или они будут отстать и вымерли. – Endless

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