Правильный способ вызова функций суперкласса из подкласса

У меня есть "SuperClass" с "info" как переменная экземпляра. "SuperClass" имеет функцию "printInfo()". "printInfo()" необходимо получить доступ к переменной экземпляра "info". Я хочу создать "SubClass" , который также имеет метод "printInfo()". Я хочу вызвать printInfo() из "SuperClass" из "printInfo()" в "SubClass" .

SuperClass = function()
{
    this.info = "I am superclass";
    console.log("SuperClass:");
};

SuperClass.prototype.printInfo = function(that)
{
    console.log("printing from superclass printInfo");
    console.log(that.info);
};

SubClass = function(){};

SubClass.prototype = new SuperClass();

SubClass.prototype.printInfo = function()
{
    console.log("calling superclass");
    this.constructor.prototype.printInfo(this);
    console.log("called superclass");
};

var sc = new SubClass();
sc.printInfo();

Вы можете видеть, что я передаю "это" как параметр для printInfo. Без "этого" параметра "информация" печатается как "undefined". Как и в следующем случае, "this.info" undefined, когда эта функция вызывается из объекта "SubClass" .

SuperClass.prototype.printInfo = function()
    {
        console.log("printing from superclass printInfo");
        console.log(this.info);
    };

Каков правильный способ переопределения и вызова методов суперкласса в javascript, позволяя функциям обращаться к переменным экземпляра класса?

Ответы

Ответ 1

Вы возились с прототипом SubClass с объектом SuperClass, в этой строке

SubClass.prototype = new SuperClass();

прототип ребенка должен зависеть от прототипа родителя. Таким образом, вы можете наследовать так:

SubClass.prototype = Object.create(SuperClass.prototype);

Кроме того, вполне нормально менять конструктор на фактическую функцию, например,

SubClass.prototype.constructor = SubClass;

Чтобы сохранить общую реализацию, вы можете использовать Object.getPrototypeOf, чтобы получить родительский прототип в цепочке наследования, а затем вызвать printInfo, вроде этого

SubClass.prototype.printInfo = function() {
    Object.getPrototypeOf(SubClass.prototype).printInfo(this);
};

Так как info определяется в SubClass, он будет печатать undefined. Вы также можете вызвать конструктор parent't, например

var SubClass = function() {
    SuperClass.call(this);
};

Примечание.. Вы создаете глобальные переменные, опуская ключевое слово var до SuperClass и SubClass.

Ответ 2

После прочтения всех ответов я использую следующий механизм наследования:

var SuperClass = function()
{
    this.info = "I am superclass";
    console.log("SuperClass:");
};

SuperClass.prototype.printInfo = function()
{
    console.log("printing from superclass printInfo");
    console.log("printinfo");
    console.log(this.info);
};

var SubClass = function(){
    SuperClass.call(this);
};

SubClass.prototype = Object.create(SuperClass.prototype);

SubClass.prototype.printInfo = function()
{
    console.log("calling superclass");
    Object.getPrototypeOf(SubClass.prototype).printInfo.call(this);
    console.log("called superclass");
};

var sc = new SubClass();
sc.printInfo();

Ответ 3

Вы можете написать это следующим образом:

SuperClass.prototype.printInfo = function(){
  console.log("printing from superclass printInfo");
  console.log(this.info); 
};

SubClass.prototype.printInfo = function(){
  console.log("calling superclass");
  SuperClass.prototype.printInfo.call(this);
  console.log("called superclass");
};

Ответ 4

@coolscitist

Вместо

SubClass.prototype.printInfo = function()
{
    Object.getPrototypeOf(SubClass.prototype).printInfo.call(this);
};

используйте этот

SubClass.prototype.printInfo = function()
{
    Object.getPrototypeOf(this.constructor.prototype).printInfo.call(this);
};

Ответ 5

Для всех, кто приходит больше из мира Java, я проигнорировал бы все вышеизложенное и вместо этого использовал следующий синтаксис, который был представлен в 2015 году

class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

class Square extends Polygon {
  constructor(sideLength) {
    super(sideLength, sideLength);
  }
  get area() {
    return this.height * this.width;
  }
  set sideLength(newLength) {
    this.height = newLength;
    this.width = newLength;
  }
} 

Дополнительная информация о https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

И suddently u может использовать супер как ключевое слово для доступа к ancester и т.д.... Для меня это было большим облегчением