javascript hasOwnProperty原型和继承

时间:2017-02-05 13:41:07

标签: javascript properties prototypal-inheritance

我检查过问题: javascript what is property in hasOwnProperty?  和 javascript hasOwnProperty and prototype 但无法找到问题的答案。这是我的代码: 但是有些答案令我感到困惑(不像预期的那样)。



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已经检测到这些方法。令人费解。谢谢。

2 个答案:

答案 0 :(得分:2)

首先要注意的是,使用new School设置Student.prototype是一种反模式。这是一种反模式,你看到很多,但它是一种反模式。 (这也很奇怪:StudentSchool有一个“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

您没有看到原型方法的原因是因为getOwnPropertyNames仅显示在您调用它的对象上直接设置的属性的名称(新的School对象和新的{{ 1}}对象)。这些方法不是直接设置的,它们是在这些对象的原型上设置的。所以他们没有列出。

重新反模式:在ES5和更早的语法中,使用构造函数设置原型继承的正确方法是通过Student,而不是调用构造函数。此外,在替换函数的Object.create属性上的对象之后,将其prototype属性设置回原来的属性是有用的:

constructor

当然,在ES2015(又名“ES6”)及更高版本中,您可以使用Student.prototype = Object.create(School.prototype); Student.prototype.constructor = Student; 表示法(如果旧浏览器有必要进行转换),它会为您正确处理。

答案 1 :(得分:0)

可能是混淆的一部分是hasOwnProperty不能像你想象的那样构造函数。 但是按照你对实例的预期工作:

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