Javascript 从子类调用超类函数的正确方法

Javascript 从子类调用超类函数的正确方法,javascript,inheritance,prototypal-inheritance,Javascript,Inheritance,Prototypal Inheritance,我有一个以“info”作为实例变量的“超类”。“超类”具有函数“printInfo()”。“printInfo()”需要访问实例变量“info”。 我想创建一个“子类”,它也有方法“printInfo()”。我想从“子类”的“printInfo()”调用“超类”的printInfo() 您可以看到,我正在将“that”作为参数传递给printInfo。如果没有“该”参数,“信息”将打印为“未定义”。与下面的情况类似,当从“SubClass”的对象调用此函数时,“this.info”是未定义的 在

我有一个以“info”作为实例变量的“超类”。“超类”具有函数“printInfo()”。“printInfo()”需要访问实例变量“info”。 我想创建一个“子类”,它也有方法“printInfo()”。我想从“子类”的“printInfo()”调用“超类”的printInfo()

您可以看到,我正在将“that”作为参数传递给printInfo。如果没有“该”参数,“信息”将打印为“未定义”。与下面的情况类似,当从“SubClass”的对象调用此函数时,“this.info”是未定义的


在javascript中重写和调用超类的方法,使函数能够访问类的实例变量的正确方法是什么?

您可以这样编写:

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");
};

在这一行中,您正在处理
子类的原型和
超类的对象

SubClass.prototype = new SuperClass();
孩子的原型应该依赖于父母的原型。所以,你可以这样继承

SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;
SubClass.prototype.printInfo = function() {
    Object.getPrototypeOf(SubClass.prototype).printInfo(this);
};
var SubClass = function() {
    SuperClass.call(this);
};
另外,将构造函数更改为实际函数是非常正常的,如

SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;
SubClass.prototype.printInfo = function() {
    Object.getPrototypeOf(SubClass.prototype).printInfo(this);
};
var SubClass = function() {
    SuperClass.call(this);
};
为了保持实现的通用性,您可以使用获取继承链中的父原型,然后调用
printInfo
,如下所示

SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;
SubClass.prototype.printInfo = function() {
    Object.getPrototypeOf(SubClass.prototype).printInfo(this);
};
var SubClass = function() {
    SuperClass.call(this);
};
由于,
info
是在
子类中定义的,因此它将打印
未定义的
。您可能还希望调用父级的t构造函数,如下所示

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

注意:您正在创建全局变量,通过在
超类
子类
之前省略
var
关键字,在阅读所有答案后,我使用以下继承机制:

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.constructor = SubClass;

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();
@苦行僧

而不是

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

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

对于更多来自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;
  }
} 
更多关于


突然你可以用super作为关键字来访问ancester等。。。。对我来说,这是一个很大的解脱

我能够解决这个问题的唯一方法是在重写子类定义之前,将父函数保存在不同的变量中

class Thing {
  constructor(age) { this.age = age; }
  die(how) { console.log(`Died of ${how}`); }
}

class Me extends Thing {
  constructor() { super(59); console.log(`I am ${this.age}`); }
  // Refer to a method from the superclass that is overridden in the subclass
  die(how) { super.die('liver failure'); console.log(`while ${how}`) }
}

(new Me()).die('hang gliding');
var Foo = function(){
    var self = this.
    this.init = function(a,b){
        self.a = a;
        seld.b = b;
    };
}

var Goo = function(){
    Foo.apply(this);
    var self = this;
    self.Foo = { init: self.init };//saves the super class's definition of init in a new variable
    self.init = function(a,b,c){
       self.Foo.init(a,b);//can call the super class function
       self.c = c;
    };
}

var a = new Foo();
a.init(1,2);
var b = new Goo();
b.init(1,2,3);

可能是的重复项,为了保持通用性,我使用Object.getPrototypeOf(Subclass.prototype.constructor.call)调用了超级构造函数(this)。这与调用超级类函数的方式相同。虽然我不确定这是不是正确的方法,但我不是js工作原理的专家。从
Subclass.printInfo()
Superclass.printInfo()
的调用不是
Object.getPrototypeOf(Subclass.prototype).printInfo.call(this)
而不是
…printInfo(this)?
我这样问是因为我尝试了你的方法,但得到了一个关于
未定义的错误。我不是JS专家,所以我不清楚为什么这两种方法都有效或无效。@thefourtheye如果你想真正干净,你可以说
Object.getPrototypeOf(Object.getPrototypeOf(this))
@greatbigborect。您需要
.call(this)
,这样被调用方法中的
this
将与调用方法中的相同。您还需要设置构造函数,SubClass.prototype.constructor=SubClass谢谢。只有你的解决方案对我有效。其他答案称超类方法为ok,但出现未定义的“this”错误。不,这不是ok。假设从
子类继承一个新类
Class3
,调用
Class3
的printInfo()将导致无限循环。这是因为上面的
This.constructor
总是给出
Class3
而不是
SubClass
,即一遍又一遍地调用
Class3
的超类(SubClass)的printInfo函数。这正是我想要的。不幸的是,
super
只能在构造函数中使用。幸运的是,@Offirmo错了。:-)请看下面我的答案。这正是我想要的。谢谢这应该是公认的答案。简单,并使用新的
语法