Как мне переопределить родительский метод в Javascript? - PullRequest
3 голосов
/ 02 ноября 2019

давайте предположим, что у нас есть объект 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 ]

1 голос
/ 02 ноября 2019

ОБНОВЛЕННЫЙ ОТВЕТ: Теперь, когда я дома и на ноутбуке, я вижу ошибку. Вы установили прототип Учителя не в том месте.

Так что вам нужно было сделать следующее:

// 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. Поэтому независимо от того, на что вы установили прототип Учителя, он перезаписывался.

0 голосов
/ 02 ноября 2019

Проблема в том, что вы определяете greeting как метод экземпляра в Person. Это должен быть метод Person.prototype. Почему? Потому что, когда вы ссылаетесь на свойство экземпляра, интерпретатор всегда сначала проверяет наличие свойств экземпляра, затем свойства прототипа конструктора экземпляра.

Так что это должноработа:

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;
  }
}
0 голосов
/ 02 ноября 2019

В вашем первом классе greeting функция на прототипе функции Person. Если вы используете this в функции конструктора, то вы ссылаетесь на вновь созданный объект, а не на прототип функции. Это правильный способ, если вы хотите переопределить функцию-прототип:

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

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

Вы можете сравнить этот код с вашим, проверив значение Person.prototype.greeting.

Вот почему вы не можете переопределить его с помощью класса Teacher, потому что функция greeting перезаписывается конструктором Person каждый раз, когда вы создаете объект Teacher и вызываете его конструктор.

...