Call parent method in JavaScript class but stll ha

2019-06-12 12:18发布

Is it possible to call parent method in JavaScript class but to still have access to prototype methods from parent and child class. Here is code example:

var Base = function() {

  this.baseMethod = function(){
    return 'baseMethod';
  };

  this.baseInitMethod = function() {
    return 'baseInitMethod';
  }
}


Base.prototype.basePrototypeMethod = function() {
  return "basePrototypeMethod";
};


var Specific = function() {

  Base.call(this);

  this.baseInitMethod = function() {
    // call baseInitMethod from Base class
  }

  this.specificMethod = function(){
    return 'specificMethod';
  }

  this.specificInitMethod = function() {

    return this.basePrototypeMethod();
  }
}


Specific.prototype.specificPrototypeMethod = function() {
  return 'specificPrototypeMethod' + '-' + this.baseInitMethod();
}


for(var p in Base.prototype) {
   Specific.prototype[p] = Base.prototype[p]
}


var s = new Specific();


console.log(s.baseMethod());

console.log(s.baseInitMethod());

console.log(s.basePrototypeMethod());

console.log(s.specificMethod());

console.log(s.specificInitMethod());

console.log(s.specificPrototypeMethod());

I want to call baseInitMethod in Base class from baseInitMethod method inside Specific class but so that all function calls from above still works. Is that possible?

5条回答
女痞
2楼-- · 2019-06-12 13:01
class Parentable {
  get parent() {
    return this.__proto__.__proto__;
  }
} 
class A extends Parentable { 
  say() { 
    console.log('Hello from A'); 
  } 
}
class B extends A {
  say() {
   console.log('Im not A, I am B! But A send you a message:');
   this.parent.say();
  }
}
(new B()).say();
查看更多
走好不送
3楼-- · 2019-06-12 13:02

Your Specific.prototype object should inherit from the Base.prototype object. Currently you're copying over all its properties to the object with this code:

for(var p in Base.prototype) {
   Specific.prototype[p] = Base.prototype[p]
}

But you should actually use Object.create to establish a real prototype chain:

Specific.prototype = Object.create(Base.prototype);

Specific.prototype.specificPrototypeMethod = function() {
  return 'specificPrototypeMethod' + '-' + this.baseInitMethod();
}

I want to call baseInitMethod in Base class from baseInitMethod method inside Specific class

Yes. In your Specific constructor, you first need get Base's baseInitMethod instance method, before you overwrite the property of the instance:

function Specific() {
    Base.call(this);

    var parentInitMethod = this.baseInitMethod;
    this.baseInitMethod = function() {
        // call baseInitMethod from Base class:
        parentInitMethod.call(this /*, arguments…*/); 
    }

    …
}

so that all function calls from above still works.

I'm not sure what you mean by that exactly. The specificPrototypeMethod will always call the baseInitMethod of the current instance, which would be Specific's overwritten one not the original that was defined in Base.

查看更多
Juvenile、少年°
4楼-- · 2019-06-12 13:08

You're overwriting the baseInitMethod of Base inside Specific, with Specific's definition, so why would you ever want to call the Base version? If you simply remove the overwrite of the function you should call the Base definition:

var Base = function() {

  this.baseMethod = function(){
    return 'baseMethod';
  };

  this.baseInitMethod = function() {
    return 'baseInitMethod';
  }
}


Base.prototype.basePrototypeMethod = function() {
  return "basePrototypeMethod";
};


var Specific = function() {

  Base.call(this);

  this.baseInitMethod(); // calls the Base definition only

  this.specificMethod = function(){
    return 'specificMethod';
  }

  this.specificInitMethod = function() {

    return this.basePrototypeMethod();
  }
}
查看更多
Juvenile、少年°
5楼-- · 2019-06-12 13:09

Here is what you need to do:

var Base = function () {
};
Base.prototype.baseMethod = function () {
    return 'baseMethod';
};
Base.prototype.baseInitMethod = function () {
    return 'baseInitMethod';
};
Base.prototype.basePrototypeMethod = function () {
    return "basePrototypeMethod";
};


var Specific = function () {
    Base.apply(this, arguments);
};
Specific.prototype.baseInitMethod = function () {
    Base.prototype.baseInitMethod.apply(this,arguments);
};

Specific.prototype.specificMethod = function () {
    return 'specificMethod';
};

Specific.prototype.specificInitMethod = function () {
    var basePrototypeMethodCallResult = Base.prototype.basePrototypeMethod.apply(this,arguments);

};
查看更多
We Are One
6楼-- · 2019-06-12 13:10

One might argue "Why always trying to mimic 'classical' behaviour and fuss with call and apply instead of embracing the prototype delegation pattern instead?"

Here is what I would code :

var Base = {

    baseVariable1: "baseValue1",

    baseVariable2: "baseValue2",

    baseMethod: function () {
        return 'baseMethod';
    },

    baseInitMethod: function () {
        return 'baseInitMethod';
    }
}

var Specific = Object.create(Base);

Specific.variable1 = "value1";

Specific.variable2 = "value2";

Specific.specificInitMethod = function () {
    return 'specificInitMethod' + '-' + this.baseInitMethod();
}

Specific.specificMethod = function () {
    return 'specificMethod' + '-' + this.baseInitMethod();
}

var s = Object.create(Specific);

console.log(s.baseInitMethod());

console.log(s.baseVariable1);

console.log(s.baseVariable2);

console.log(s.variable1);

console.log(s.variable2);

console.log(s.baseMethod());

console.log(s.specificInitMethod());

console.log(s.specificMethod());
查看更多
登录 后发表回答