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

coo*_*ist 30 javascript inheritance prototypal-inheritance

我有一个"SuperClass","info"作为实例变量."SuperClass"具有"printInfo()"功能."printInfo()"需要访问实例变量"info".我想创建一个"分类"里面也有方法"printInfo()".我想从"子类"的"printInfo()"称之为"超类"的printInfo().

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();
Run Code Online (Sandbox Code Playgroud)

你可以看到,我路过""作为一个参数printInfo.如果没有"说"参数,"信息"打印为"不确定".就像在以下情况下,"this.info"当此功能从"子类"的对象调用是不确定的.

SuperClass.prototype.printInfo = function()
    {
        console.log("printing from superclass printInfo");
        console.log(this.info);
    };
Run Code Online (Sandbox Code Playgroud)

什么是覆盖并调用在JavaScript超类的方法,使函数访问类的实例变量的正确方法?

the*_*eye 27

你正在用这个对象弄乱SubClass原型的原型SuperClass

SubClass.prototype = new SuperClass();
Run Code Online (Sandbox Code Playgroud)

孩子的原型应该取决于父母的原型.所以,你可以像这样继承

SubClass.prototype = Object.create(SuperClass.prototype);
Run Code Online (Sandbox Code Playgroud)

此外,这是很正常的构造改变到实际功能,这样

SubClass.prototype.constructor = SubClass;
Run Code Online (Sandbox Code Playgroud)

为了使您的实现保持通用,您可以使用Object.getPrototypeOf,在继承链中获取父原型,然后printInfo像这样调用

SubClass.prototype.printInfo = function() {
    Object.getPrototypeOf(SubClass.prototype).printInfo(this);
};
Run Code Online (Sandbox Code Playgroud)

因为,info在定义SubClass是,它会打印undefined.您可能还需要调用parent't构造,像这样

var SubClass = function() {
    SuperClass.call(this);
};
Run Code Online (Sandbox Code Playgroud)

注意:您正在通过varSuperClass和之前省略关键字来创建全局变量SubClass.

  • 从Subclass.printInfo()到Superclass.printInfo()的调用不是Object.getPrototypeOf(SubClass.prototype).printInfo.call(this),而不仅仅是... printInfo(this)我问,因为我按您的方式尝试并收到有关“未定义”的错误。我不是JS专家,所以我不清楚为什么这两种方法都能奏效。 (2认同)

coo*_*ist 9

阅读完所有答案后,我使用以下继承机制:

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();
Run Code Online (Sandbox Code Playgroud)


Cam*_*ntz 6

你可以像这样写:

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");
};
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 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;
  }
} 
Run Code Online (Sandbox Code Playgroud)

更多信息请访问https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

突然间你可以使用 super 作为关键字来访问祖先等......对我来说发现这是一个很大的解脱

  • 幸运的是,@Offirmo 错了。:-) 请参阅下面我的回答。 (2认同)

Den*_*owe 5

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');
Run Code Online (Sandbox Code Playgroud)