Reputation: 577
I've checked questions: javascript what is property in hasOwnProperty? and javascript hasOwnProperty and prototype but couldn't find the answer to my problem. Here is my code: But some answers are puzzling me (NOT as expected).
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
The last 2 alerts don't mention the methods, though these methods have been detected by hasOwnProperty. Puzzling. Thank you.
Upvotes: 1
Views: 586
Reputation: 1074505
The first thing to note is that using new School
to set up Student.prototype
is an anti-pattern. It's an anti-pattern you see a lot, but it's an anti-pattern. (It's also bizarre: Student
has an "is-a" relationship with School
?! Normally there'd be a "has-a" relationship [not inheritance], but not an "is-a"...) We'll come back to it.
Answering:
console.log(Student.prototype.hasOwnProperty("studentName")); // NOT as expected: false
Nothing ever sets a studentName
property on Student.prototype
, so it's no surprise that it doesn't have the property. The Student
function will set one on the instance when you call it, but Student.prototype
isn't an instance created by new Student
, so it's never had one set on it.
Moving on to:
console.log(School.prototype.hasOwnProperty("schoolName")); // NOT as expected: false
Same explanation.
Moving on to:
console.log(Object.getOwnPropertyNames(new School())); // schoolName console.log(Object.getOwnPropertyNames(new Student())); // studentName, schoolName
The reason you don't see the prototype methods there is because getOwnPropertyNames
shows only the names of properties directly set on the object you call it on (the new School
object and the new Student
object). The methods aren't directly set on those, they're set on the prototype of those objects. So they're not listed.
Re the anti-pattern: In ES5 and earlier syntax, the correct way to set up prototypical inheritance with constructor functions is via Object.create
, not calling the constructor. Also, after replacing the object on a function's prototype
property, it's useful to set its constructor
property back to what it should be:
Student.prototype = Object.create(School.prototype);
Student.prototype.constructor = Student;
Of course, in ES2015 (aka "ES6") and later, you can use class
notation (transpiling if necessary for older browsers), which handles doing it correctly for you.
Upvotes: 3
Reputation: 7878
maybe part of the confusion is hasOwnProperty doesn't work as you think for constructor function. But works as you'd expect for the instance:
a = new Student()
a.hasOwnProperty("studentName") //true
Upvotes: 0