2012-05-23 7 views
0

Я изучал классы в JavaScript, использование прототипа и, наконец, как наследовать.Прототип и наследование в JavaScript не работает, как я ожидаю

Из моего понимания ниже следует:

  1. оповещения «Джон» из-за myInstance.getIt(); который называют
  2. оповещения «Джек» из-за myInheritedInstance.getIt(); который называют
  3. myInheritedInstance.getParent(); был назначен .getIt() в MyClass
  4. Это должно тогда предупредить «Джон», когда myInheritedInstance.getParent(); называется.

Вместо того, что происходит на самом деле:

  1. оповещения "Джон"
  2. оповещения Blank
  3. оповещения "Jack"

У меня есть чувство, что я сделал что-то глупое или неправильно поняли здесь фундаментальную концепцию, поэтому любая помощь будет оценена по достоинству.

var MyClass = function() { }; 

MyClass.prototype.constructor = MyClass; 
MyClass.prototype.name = "John"; 
MyClass.prototype.getIt = function() { alert(this.name); }; 

var myInstance = new MyClass(); 
myInstance.getIt(); 

//Now inheritance 

var MyInheritedClass = function() { }; 
MyInheritedClass.prototype = new MyClass; 
MyInheritedClass.prototype.constructor = MyInheritedClass; 
MyInheritedClass.prototype.name = "Jack"; 
MyInheritedClass.prototype.getIt = function() { alert(this.name); }; 
MyInheritedClass.prototype.getItParent = MyClass.prototype.getIt.call(this); 

var myInheritedInstance = new MyInheritedClass(); 
myInheritedInstance.getIt(); 
myInheritedInstance.getItParent(); 

ответ

3

Виной:

MyInheritedClass.prototype.getItParent = MyClass.prototype.getIt.call(this); 

.call будет вызов функция, не возвращение один. Таким образом, это вызовет две проблемы: он вызывает это заранее и возвращает то, что не может быть вызвано (вы получаете сообщение об ошибке в консоли). Вы должны были бы сделать:

MyInheritedClass.prototype.getItParent = function() { 
    alert(Object.getPrototypeOf(Object.getPrototypeOf(this)).name); 
}; 

Проблема заключается в том, что name не доступна через this больше, как это было в тени над унаследованным классом. Чтобы получить name исходного класса, вам нужно пройти цепочку прототипов два раза: inherited instance -> inherited prototype -> original prototype.

Линия

MyClass.prototype.constructor = MyClass; 

не нужно здесь, кстати. Восстановление constructor необходимо в случае, если вы переписываете prototype, потому что constructor теряется в этом случае. Поэтому в вашем случае это необходимо только для унаследованного класса.

Кроме того, линия

MyInheritedClass.prototype.getIt = function() { alert(this.name); }; 

является излишним, это так же, как MyClass.prototype.getIt - который вы унаследовали.

Обратите внимание, что JavaScript не содержит реальных «классов», хотя их поведение может быть выполнено следующим образом.

+0

Спасибо за разъяснение. Я думаю, что проблема в том, что я работал из не очень правильного учебника. Таким образом, нет способа получить переопределенные методы и значения базового класса с помощью вызова? Это пример, на котором вы показываете единственный способ «добраться» от них? – Nealbo

+0

И да, я думаю, что добавление getIt в MyInheritedClass было моим собственным небольшим «faux pas», который я привел в ситуацию! – Nealbo

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