2013-05-02 6 views
0

Почему это говорит «Animal» вместо «kitty»?Попытка понять наследование в JavaScript - что здесь происходит?

// create base class Animal 
function Animal(animalType) { 
    this.type = animalType; 
    this.sayType = function() { 
     alert(this.type); 
    }; 
} 

// create derived class Cat 
function Cat(myName) { 
    Animal.call(this, "cat"); // cat calls the Animal base class constructor 

    this.name = myName; 

    this.sayName = function() { 
     alert(this.name); 
    }; 
} 

Cat.prototype = Object.create(Animal); // set Cat's prototype to Animal 

// instantiate a new instance of Cat 
var cat = new Cat("kitty"); 

cat.sayName(); 
cat.name = "lol"; 
cat.sayName(); 

http://jsfiddle.net/dgcoffman/MguUA/5/

+2

ваши '' функции sayType' и sayName' är фактически используют прототипное наследование, потому что они не на прототипе! Вы создали их как локальные свойства экземпляра. – Alnitak

ответ

4
Object.create(Animal); // set Cat's prototype to Animal 

Да, но функции Animal конструктора (или, если быть точным: на новый объект наследует от этой функции объекта - проверить docs for Object.create). Это вряд ли то, что вы хотите - и объясняет ваш любопытный результат: "Animal", так как это Animalfunction's name property.

Вместо этого, вы хотите построить цепочку прототипов, так что экземпляры кошек наследуют от Cat.prototype который наследуется от Animal.prototype (который наследуется от Object.prototype):

Cat.prototype = Object.create(Animal.prototype); 

Кроме того, для прототипа наследования, вы должны, но в sayName и sayType методы объекта-прототипа (и только один раз):

Animal.prototype.sayType = function() { 
    alert(this.type); 
}; 
Cat.prototype.sayName = function() { // after creation of that object, of course 
    alert(this.name); 
}; 
+0

OK Я признаю, что, возможно, это то, что он хочет сделать; так как прототип Animal не упоминается вообще, это не произошло со мной. Это, однако, возможность. – Pointy

+0

Спасибо за ответ. Когда я делаю это, я получаю неперехваченный TypeError: Объект # не метода http://jsfiddle.net/dgcoffman/MguUA/7/ Nevermind, я перезапись прототипа кошек после того, как я добавил функцию sayName «sayName» к нему, исправлено: http://jsfiddle.net/dgcoffman/MguUA/8/ –

1

Вы звоните в пути, который делает что-то другое, чем то, что я держал пари, вы думаете, что делает Object.create(). Попробуйте это изменение:

Cat.prototype = Object.create(new Animal); 

Object.create() функция ожидает, что ее первый аргумент, чтобы быть объекта для использования в качестве прототипа для возвращаемого объекта. Когда вы передаете имя функции «Animal», это означает, что вы хотите, чтобы объект-прототип был тем функциональным объектом, а не объектом , созданным функцией.

редактировать — ответ Берги в вовлечение непосредственного использования животного прототипа, вероятно, имеет больше смысла, хотя от того, что вы вывесили там не животное прототип объекта с ничего интересного на нем. Возможно, это где-то еще в вашем коде, или будет добавлено позже. В любом случае, если он существует, лучше делать то же, что и в его ответе.

Поскольку ваш конструктор «Cat» сразу же набирает свойство «sayType» из конструктора Animal, неясно, что вы пытаетесь сделать, установив прототип Cat.

+2

Нет. Вы знаете лучше. – Bergi

+0

@ Bergi huh? Вы делаете меня безумным здесь :-) Это заставляет скрипку работать, как я думаю, она должна работать, но я признаю, что я не уверен, почему переопределение «имени» с «котенком» не работает. Это также сбивает с толку, потому что установка прототипа глупо, учитывая '.call()' в конструкторе Cat. – Pointy

+0

Я знаю JS лучше, чем 99% людей здесь, но прототипное наследство все еще меня смущает :( – Alnitak

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