2017-02-05 13 views
1

Я проверил вопросы: javascript what is property in hasOwnProperty? и javascript hasOwnProperty and prototype , но не смог найти ответ на мою проблему. Вот мой код: Но некоторые ответы озадачивают меня (НЕ, как ожидалось).Javascript hasOwnProperty прототип и наследование

function School(schoolName) { 
 
    this.schoolName = schoolName; 
 
} 
 
School.prototype.printSchoolName = function() { 
 
    console.log(this.schoolName); 
 
} 
 

 
function Student(studentName, schoolName) { 
 
    this.studentName = studentName; 
 
    this.schoolName = schoolName; // alternative : School.call(this, schoolName); 
 
} 
 
Student.prototype = new School(); // force l'héritage des propriétés de School 
 
Student.prototype.printStudentName = function() { 
 
    console.log(this.studentName); 
 
} 
 
var s = new Student("Victor", "IUT"); 
 
s.printStudentName(); // works fine 
 
s.printSchoolName(); // works fine 
 
console.log(Student.prototype.hasOwnProperty("printStudentName")); // works as expected: true 
 
console.log(Student.prototype.hasOwnProperty("printSchoolName")); // works as expected: false 
 
console.log(Student.prototype.hasOwnProperty("studentName")); // NOT as expected: false 
 
console.log(School.prototype.hasOwnProperty("schoolName")); // NOT as expected: false 
 
console.log(Object.getOwnPropertyNames(new School())); // schoolName 
 
console.log(Object.getOwnPropertyNames(new Student())); // studentName, schoolName

Последние 2 предупреждений не упоминают методы, хотя эти методы были обнаружены hasOwnProperty. Непонятные. Спасибо.

+0

Скажите **, что ** вы ожидали, что вы видите вместо этого, и почему это не то, что вы ожидаете. –

+1

BTW после моего неудачного ответа Я также вижу, что ваше наследство нереально ... Студент наследует школу? –

+1

Почему вы ожидали, что 'Student.prototype' будет иметь собственное свойство' studentName'? И что вы ожидали от его ценности? – Bergi

ответ

0

Возможно, часть путаницы hasOwnProperty не работает, поскольку вы думаете о функции конструктора. Но работает, как и следовало ожидать для экземпляра:

a = new Student() 
a.hasOwnProperty("studentName") //true 
2

Первое, что нужно отметить, что с помощью new School для установки Student.prototype является анти-модель. Это анти-шаблон, вы видите лот, но это анти-шаблон. (Это также странно: Student имеет отношения «is-a» с School?! Обычно должно существовать отношение «has-a» [не наследование], но не «is-a» ...). Мы будем вернитесь к нему.

Ответ на:

console.log(Student.prototype.hasOwnProperty("studentName")); 
// NOT as expected: false 

Ничто никогда не устанавливает studentName собственность на Student.prototype, так что не удивительно, что она не обладает свойством. Функция Student будет устанавливать один из экземпляра , когда вы его вызываете, но Student.prototype не является экземпляром, созданным new Student, поэтому на нем никогда не было установленного.

Переходя к:

console.log(School.prototype.hasOwnProperty("schoolName")); 
// NOT as expected: false 

Такое же объяснение.

Переходя к:

console.log(Object.getOwnPropertyNames(new School())); 
// schoolName 
console.log(Object.getOwnPropertyNames(new Student())); 
// studentName, schoolName 

Причина вы не видите методы прототипа Eсть потому getOwnPropertyNames показывает только имена свойств, непосредственно установленных на объекте вы называете его включения (новый объект School и новый объект Student). Методы непосредственно не установлены на них, они установлены на прототипе этих объектов. Поэтому они не указаны.


Re анти-паттерн: В ES5 и более ранних версиях синтаксиса, правильный способ настроить прототипичное наследование функций конструктора через Object.create, не вызывая конструктор.Кроме того, после замены объекта на функции в prototype собственности, полезно установить его свойство constructor обратно к тому, что он должен быть:

Student.prototype = Object.create(School.prototype); 
Student.prototype.constructor = Student; 

Конечно, в ES2015 (так называемый «ES6»), а затем, вы можете использовать class нотация (пересылка, если необходимо, для более старых браузеров), которая обрабатывает это правильно для вас.

+0

Хорошо, спасибо. Ваш ответ немного яснее для меня. Что касается сценариев «antipattern», я должен признаться, что я взял этот фрагмент из какого-то источника в Интернете, но в любом случае я пытался разобраться, где я был не прав, ожидая чего-то еще: я подозревал, что добавление метода к прототипу было simlar чтобы написать this.mymethod: function() ... –

+0

@ allezl'OM: Да, боюсь, вы видите это повсюду, поэтому я и хотел назвать это, чтобы вы знали, что делать , :-) –