Below is the code snippet, where I have defined 'run' method in the constructor unlike 'eat' method which is defined in the prototype. How can i access this 'run' method from B1's prototype which is inherited from A1. My intension is to override 'run' method in B1 where I can use existing 'run' method of A1. Is there any way to achieve it?
function A1() { this.run = function() { return 'A1 runs'; } }; A1.prototype.eat = function() { return 'A1 eats'; }; function B1() { A1.call(this); }; B1.prototype = Object.create(A1.prototype); //new A1(); B1.prototype.eat = function() { return A1.prototype.eat.call(this) + ',B1 also eats'; } B1.prototype.run = function() { var parentRun = this.constructor.run(); var result = parentRun + ",B1 also runs"; return result; }; var b1 = new B1(); b1.eat(); // It will give 'A1 eats, B1 also eats', which is fine b1.run(); // It will give 'A1 runs', where I want 'A1 runs, B1 also runs'.
Edit 1: I have updated the code snippet, i have removed the console.log and returned the string from each method.
Initially i did not put my research about this. A few people have mentioned it duplicate of this , I had gone through the same link but my question is totally different. I know how to call a method of Parent class's prototype which I have done for "eat".
My query is simple,
is there any way to access the methods of Parent class's constructor ('run' method), not the method of prototype ('eat' method)?
Three issues:
The run
that A1
puts on instances doesn't return anything, so calling it yields undefined
.
A1
puts run
on the instance , which means that in your b1
instance, B1.prototype.run
has been obscured by the run
that A1
assigned directly to the instance.
this.constructor.run()
isn't how you would call the A1
version.
If you put run
on A1.prototype
, you can do it:
function A1() {
}
A1.prototype.eat = function() {
console.log('A1 eats');
};
A1.prototype.run = function() {
return 'A1 runs';
};
function B1() {
A1.call(this);
}
B1.prototype = Object.create(A1.prototype);
B1.prototype.run = function() {
return A1.prototype.run.call(this) + ",B1 also runs";
};
var b1 = new B1();
console.log(b1.run());
That's ugly, which is why I wrote a script to automate supercalls back in the day , but it's how you do it when working at this level.
These days, though, you'd use ES2015's class
syntax and super
instead, transpiling with Babel or Traceur or similar if necessary to support obsolete JavaScript engines:
class A1 { eat() { console.log("A1 eats"); } run() { return "A1 runs"; } } class B1 extends A1 { run() { return super.run() + ",B1 also runs"; } } var b1 = new B1(); console.log(b1.run());
Re your edit saying you don't want run
to be on the prototype, that it has to be assigned by A1
like this:
function A1() {
this.run = function() {
return 'A1 runs';
};
}
That's a bit more of a hassle, but you can still do it. For the reason I stated above, setting run
on the instance will obscure the B1.prototype.run
that your instance would normally use. So to use that, but also call A1
's non-prototype run
, you have to replace it on the instance.
For that reason, it would make sense to define B1
's run
in B1
rathr than on B1.prototype
, just like A1
defines it in A1
, not on A1.prototype
:
function B1() {
var A1run;
A1.call(this);
A1run = this.run;
this.run = function() {
return A1run.call(this) + ",B1 also runs";
};
}
Live example:
function A1() { this.run = function() { return 'A1 runs'; }; } A1.prototype.eat = function() { console.log('A1 eats'); }; function B1() { var A1run; A1.call(this); A1run = this.run; this.run = function() { return A1run.call(this) + ",B1 also runs"; }; } B1.prototype = Object.create(A1.prototype); var b1 = new B1(); console.log(b1.run());
But if you really, really want it to be (at least partially) on B1.prototype
:
function B1() {
var A1run;
A1.call(this);
A1run = this.run;
this.run = function() {
return A1run.call(this) + B1.prototype.run.call(this);
};
}
// ...
B1.prototype.run = function() {
return ",B1 also runs";
};
Live example:
function A1() { this.run = function() { return 'A1 runs'; }; } A1.prototype.eat = function() { console.log('A1 eats'); }; function B1() { var A1run; A1.call(this); A1run = this.run; this.run = function() { return A1run.call(this) + B1.prototype.run.call(this); }; } B1.prototype = Object.create(A1.prototype); B1.prototype.run = function() { return ",B1 also runs"; }; var b1 = new B1(); console.log(b1.run());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.