2016-11-14 3 views
2

В свободное время я пытаюсь узнать немного JS, но я придерживался темы в теме.JS прототип и наследование

var person = new Person("Bob", "Smith", 52); 
 
var teacher = new Teacher("Adam", "Greff", 209); 
 

 
function Humans(firstName, lastName) { 
 
    this.firstName = firstName; 
 
    this.lastName = lastName; 
 
} 
 

 
function Person(firstName, lastName, age) { 
 
    Humans.call(this, firstName, lastName); 
 
    this.age = age; 
 
} 
 

 
Person.prototype = Object.create(Humans.prototype); 
 

 
Person.prototype.fullDetail = function() { 
 
    return this.firstName + " " + this.lastName + " " + this.age; 
 
}; 
 

 

 
function Teacher(firstName, lastName, roomNumber) { 
 
    Humans.call(this, firstName, lastName); 
 
    this.room = roomNumber; 
 
} 
 

 
Teacher.prototype = Object.create(Humans.prototype); 
 

 
Teacher.prototype.fullDetail = function() { 
 
    return this.firstName + " " + this.lastName + " " + this.room; 
 
}; 
 

 
person.fullDetail();

Может кто-нибудь сказать мне, почему я не могу выполнить person.fullDetail();?

Если бы вы могли высказать свои замечания по своей версии кода, я был бы очень благодарен, спасибо.

+3

вы создаете экземпляры до определения функции! –

+0

@ DanielA.White Подъемник фиксирует некоторые из этих – Feathercrown

+0

Подъем только применим к нескольким функциям здесь. – ssube

ответ

6

Потому что вы» создавая свои объекты, прежде чем вы определите, какими должны быть их прототипы.

Когда вы

var person = new Person ("Bob", "Smith", 52); 

вы делаете объект на основе определения Personтока. Позже в этом коде, вы изменяете прототип Person в полном комплекте

Person.prototype = Object.create(Humans.prototype); 

Чтобы исправить это, создавать объекты после вы сделали переназначение прототипа.

function Humans(firstName, lastName) { 
 
    this.firstName = firstName; 
 
    this.lastName = lastName; 
 
} 
 

 
function Person(firstName, lastName, age) { 
 
    Humans.call(this, firstName, lastName); 
 
    this.age = age; 
 
} 
 

 
Person.prototype = Object.create(Humans.prototype); 
 

 
Person.prototype.fullDetail = function() { 
 
    return this.firstName + " " + this.lastName + " " + this.age; 
 
}; 
 

 

 
function Teacher(firstName, lastName, roomNumber) { 
 
    Humans.call(this, firstName, lastName); 
 
    this.room = roomNumber; 
 
} 
 

 
Teacher.prototype = Object.create(Humans.prototype); 
 

 
Teacher.prototype.fullDetail = function() { 
 
    return this.firstName + " " + this.lastName + " " + this.room; 
 
}; 
 

 
var person = new Person("Bob", "Smith", 52); 
 
var teacher = new Teacher("Adam", "Greff", 209); 
 
console.log(person.fullDetail());

+3

Вы можете фактически доказать это, показывая, что 'Object.getPrototypeOf (person)'! == 'Person.prototype'. Прототип или оригинал - это экземпляр человека, который «потерян» и заменен. Очень интересный краевой кейс для наследования javascript! – tcooc

5

Да, это потому, что когда вы создаете объект человека, у прототипа человека нет метода FullDetail.

Изменить упорядочение вашего создания объекта, создать человек объект после добавления методов к прототипу

проверить этот фрагмент

var teacher; 
 
var person; 
 
function Humans(firstName, lastName) { 
 
    this.firstName = firstName; 
 
    this.lastName = lastName; 
 
} 
 

 
function Person(firstName, lastName, age) { 
 
    Humans.call(this, firstName, lastName); 
 
    this.age = age; 
 
} 
 

 
Person.prototype = Object.create(Humans.prototype); 
 

 
Person.prototype.fullDetail = function() { 
 
    return this.firstName + " " + this.lastName + " " + this.age; 
 
}; 
 

 
person = new Person("Bob", "Smith", 52); 
 

 
function Teacher(firstName, lastName, roomNumber) { 
 
    Humans.call(this, firstName, lastName); 
 
    this.room = roomNumber; 
 
} 
 

 
Teacher.prototype = Object.create(Humans.prototype); 
 

 
Teacher.prototype.fullDetail = function() { 
 
    return this.firstName + " " + this.lastName + " " + this.room; 
 
}; 
 
teacher= new Teacher("Adam", "Greff", 209); 
 
console.log(person.fullDetail()); 
 
console.log(teacher.fullDetail());

Надеется, что это помогает

+0

Хотя это исправляет этот случай использования, он не фиксирует того факта, что «учитель» все еще сломан! – tcooc

+0

Просто добавьте причину, по которой вы можете * создать * человека перед функцией конструктора (и изменения прототипа) из-за этой раздражающей/противоинтуитивной вещи, называемой «hoisting» https://developer.mozilla.org/ ан/Docs/Web/JavaScript/Справка/Заявления/вар # var_hoisting. – jlb

+0

@tcooc попробуйте переместить экземпляр 'teacher' ниже под конструктором' Teacher' – jlb

1

Я думаю, это потому, что вы создаете человек и учитель, не имея свои функции, определенные еще в прототипе. Попробуйте это:

function Humans(firstName, lastName) { 
 
     this.firstName = firstName; 
 
     this.lastName = lastName; 
 
    } 
 
    
 
    function Person(firstName, lastName, age) { 
 
     Humans.call(this, firstName, lastName); 
 
     this.age = age; 
 
    } 
 
    
 
    Person.prototype = Object.create(Humans.prototype); 
 
    
 
    Person.prototype.fullDetail = function() { 
 
     return this.firstName + " " + this.lastName + " " + this.age; 
 
    }; 
 
    
 
    
 
    function Teacher(firstName, lastName, roomNumber) { 
 
     Humans.call(this, firstName, lastName); 
 
     this.room = roomNumber; 
 
    } 
 
    
 
    Teacher.prototype = Object.create(Humans.prototype); 
 
    
 
    Teacher.prototype.fullDetail = function() { 
 
     return this.firstName + " " + this.lastName + " " + this.room; 
 
    }; 
 
    var person = new Person ("Bob", "Smith", 52); 
 
    var teacher = new Teacher ("Adam", "Greff", 209); 
 
    
 
    console.log(person.fullDetail());
(͡° ͜ʖ ͡°)