如何在Javascript中覆盖父母的方法?

时间:2019-11-02 16:21:38

标签: javascript prototype

假设我们有一个对象Person如下:

function Person(name){
            this.name = name;

            this.greeting = function(){
                alert("Hi I'm " + this.name);
            }
        }

及其子代

function Teacher(name, subject){
            Person.call(this, name); 
            this.subject = subject;
            Teacher.prototype = Object.create(Person.prototype);
        }

我尝试如下重写greeting方法:

Teacher.prototype.greeting = function(){                
                alert("Hello my name is " + this.name + " and I teach " + this.subject);

        }

但是teacher1.greeting()调用Person的方法,而不是Teacher的方法,如您在此处看到的:

Person's method invoked and not Teacher's one

  • 哪里出问题了?

3 个答案:

答案 0 :(得分:1)

更新的答案: 现在,我在家中并在笔记本电脑上,我看到了该错误。您将教师原型放置在错误的位置。

所以您需要这样做:

// Incorrect
function Teacher(first, last, age, gender, interest, subject) {
  Person.call(this, first, last, age, gender, interest);
  this.subject = subject;
  Teacher.prototype = Object.create(Person.prototype);
}

// Correct
function Teacher(first, last, age, gender, interest, subject) {
  Person.call(this, first, last, age, gender, interest);
  this.subject = subject;
}

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

因此,每次实例化Teacher的新实例时,都将用Person覆盖它的原型。因此,无论您将教师的原型设置为什么,它都会被覆盖。

答案 1 :(得分:0)

在Person函数原型的第一个类greeting中。 如果在构造函数中使用this,则引用的是新创建的对象,而不是函数的原型。如果要覆盖原型功能,这是正确的方法:

function Person(name){
    this.name = name;
}

Person.prototype.greeting = function(){
    alert("Hi I'm " + this.name);
}

您可以通过检查Person.prototype.greeting的值将此代码与您的代码进行比较。

这就是为什么您不能用Teacher类覆盖它,原因是greeting函数在每次创建Teacher对象并调用它的构造函数时都被Person构造函数覆盖。

答案 2 :(得分:0)

问题是您在greeting中将Person定义为 instance方法。它应该是Person.prototype的方法。为什么?因为当您引用实例的属性时,解释器总是 first 首先检查实例属性的存在,因此然后实例的构造函数原型属性。

所以这应该起作用:

const someTeacher = new Teacher("Peter", "Jones", 26, "Male", "Functional Programming", "Math");
someTeacher.greeting();

function Person(first, last, age, gender, interest) {
  this.name = {
    first,
    last
  };
  this.age = age;
  this.gender = gender;
  this.interest = interest;
  
  // set the Person.prototype greeting method
  // if not already done
  if (!Person.prototype.greeting) {
    Person.prototype.greeting = function() {
      console.log("Hi I'm " + this.name.first);
    };
  }
}

function Teacher(first, last, age, gender, interest, subject) {
  Person.call(this, first, last, age, gender, interest);
  this.subject = subject;
  
  // set Teachers prototype to Person
  // if not already done
  if (!Teacher.prototype.greeting) {
    // override [greeting] first. If you do this after
    // pointing the prototype to Person, it wil not
    // work, probably because in that case you're
    // overwriting Person.prototype.greeting which is
    // a nogo
    Teacher.prototype.greeting = function() {
      console.log("Hello my name is " + this.name.first + " and I teach " + this.subject);
    };
    // set prototype to Person
    Teacher.prototype = Person;
  }
}