在JavaScript中进行继承时方法未传递下来

时间:2018-10-03 02:51:41

标签: javascript

我有一个这样定义的函数构造函数:

var Person = function (name, yearOfBirth, job) {
            this.name = name;
            this.yearOfBirth = yearOfBirth;
            this.job = job;
        }
        Person.prototype.calculateAge = function () {
            console.log(2016 - this.yearOfBirth);
        };

现在,我还有另一个名为Teacher的函数构造函数,该函数的构造方法如下:

var Teacher = function (name, yearOfBirth, subject) {
            Person.call(this, name, yearOfBirth, "teacher");
            this.subject = subject;
        }

现在,我以这种方式创建一个名为roySir的新对象:

var roySir = new Teacher("Roy", 1960, "English");

但是当我尝试做时 roySir.calculateAge()我收到一条错误消息,说

  

“ roySir.calculateAge不是函数”

为什么不继承calculateAge函数?

enter image description here

我的另一个问题是何时检查:

roySir.hasOwnProperty("name") // true

为什么这是真的?是不是命名父类的属性而不是自己的属性?

enter image description here

1 个答案:

答案 0 :(得分:2)

您应确保Teacher的原型继承自Person的原型。仅仅用call PersonTeacher不会让Teacher继承自Person的原型方法:

var Person = function(name, yearOfBirth, job) {
  this.name = name;
  this.yearOfBirth = yearOfBirth;
  this.job = job;
}
Person.prototype.calculateAge = function() {
  console.log(2016 - this.yearOfBirth);
};
var Teacher = function(name, yearOfBirth, subject) {
  Person.call(this, name, yearOfBirth, "teacher");
  this.subject = subject;
}
Teacher.prototype = Object.create(Person.prototype);
var roySir = new Teacher("Roy", 1960, "English");
roySir.calculateAge();

您需要在那里使用Object.create而不是Teacher.prototype = Person.prototype,以便Teacher.prototype的突变不会不希望地更改不是Person的{​​{1}}-例如,如果您为Teacher提供了一种Teacher.prototype方法,则您只希望teachesClass可以访问该方法,但是您不希望泛型Teacher拥有该方法该方法。

或者,使用ES6和Person,它们更具可读性:

extends

对于class Person { constructor(name, yearOfBirth, job) { this.name = name; this.yearOfBirth = yearOfBirth; this.job = job; } calculateAge() { console.log(2016 - this.yearOfBirth); } } class Teacher extends Person { constructor(name, yearOfBirth, subject) { super(...[name, yearOfBirth, subject, 'teacher']); } } var roySir = new Teacher("Roy", 1960, "English"); roySir.calculateAge();属性,它是用name分配给对象本身的。在调用一个构造函数时,就像使用this.name = name;一样,另一个构造函数中的Person.call(this, ...)仍然直接引用在调用代码中创建的对象-this就是这样做的,传递给它的第一个参数将直接引用另一个函数中使用的call

原型链如下:

this