Calling a super function from a subclass function [duplicate] - javascript

This question already has answers here:
Javascript Class Inheritance For Functions
(2 answers)
Closed 7 years ago.
I am looking to call a superclass function within a subclass function that overrode the superclass function. For Example:
var a = function(x) {
this.val = x || 0;
};
a.prototype.print = function() {
console.log("Class A");
};
var b = function(x, y) {
this.y = y || 0;
a.call(this, x);
};
b.prototype = Object.create(a.prototype);
b.prototype.constructor = b;
b.prototype.print = function() {
console.log("b inherits from ");
// call to superclass print function (a.print)
};
How would I call the superclass print function from the subclass when the subclass already overwrote the superclass function?

You can use superclass.prototype.method.call(argThis, parameters). In your case without parameters will be a.prototype.print.call(this);
So, your code would be
var a = function(x) {
this.val = x || 0;
};
a.prototype.print = function() {
console.log("Class A");
};
var b = function(x, y) {
this.y = y || 0;
a.call(this, x);
};
b.prototype = Object.create(a.prototype);
b.prototype.constructor = b;
b.prototype.print = function() {
console.log("b inherits from ");
a.prototype.print.call(this);
};

Related

JS Inheritance example: too much recursion

Sorry for dump question I am new to js. I would like to override f2() function in D "class". But for some reason Fire Fox told me: "too much recursion". Could you please point me where recursion happening and how to make this code work as expected?
var B = function () {
};
B.prototype.f2 = function (x) {
return 2 * x;
};
var C = function () {
B.call(this);
};
var D = function () {
C.call(this);
};
D.prototype.f2 = function (x) {
return C.prototype.f2.call(this, x) * 7;
};
inherit(B, C);
inherit(C, D);
function inherit(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
}
var d = new D();
console.log(d.f2(3));
Two problems:
You need to set up the XYZ.prototype objects before you try to add properties to them. Since your inherit function creates them, you must ensure that you do things in the right order.
You have the order of the parent and child backward in your inherit calls. It's inherit(child, parent), not inherit(parent, child).
var B = function () {
};
B.prototype.f2 = function (x) {
return 2 * x;
};
var C = function () {
B.call(this);
};
inherit(C, B); // *** Moved and updated
var D = function () {
C.call(this);
};
inherit(D, C); // *** Moved and updated
D.prototype.f2 = function (x) {
return C.prototype.f2.call(this, x) * 7;
};
function inherit(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
}
var d = new D();
console.log(d.f2(3));
The ES2015 version, for comparison:
class B {
f2(x) {
return 2 * x;
}
}
class C extends B {
}
class D extends C {
f2(x) {
return super.f2(x) * 7;
}
}
const d = new D();
console.log(d.f2(3));

How to check if a value in this is a prototype value in javascript?

I've got the following code:
function test() {
this.a = 5;
this.b = 6;
}
test.prototype.b = 10;
test.prototype.c = 12;
var example = new test();
How do I find out if example.something:
A. has only a value in the function object?
B. has only a value in the prototype?
C. has a value in both the function object and prototype?
You can test the prototype to see if the value is specified in the prototype with this:
example.constructor.prototype.b
or
Object.getPrototypeOf(example).b
You can test if the property is directly on the object itself (e.g. not inherited or on the direct prototype) with:
example.hasOwnProperty("b")
You can check the properties within the object and its prototype by using the Object.keys method.
function test() {
this.a = 5;
this.b = 6;
}
test.prototype.b = 10;
test.prototype.c = 12;
var example = new test();
console.log(Object.keys(example));
console.log(Object.keys(example.__proto__));
This code reveals this:
function test() {
this.a = 5;
this.b = 6;
}
test.prototype.b = 10;
test.prototype.c = 12;
var example = new test();
for (prop of ['a', 'b', 'c']) {
if (example.hasOwnProperty(prop)) console.log(prop + ' is owned by the object');
if (test.prototype.hasOwnProperty(prop)) console.log(prop + ' is owned by the object prototype');
}

Objects that can calculate their own properties using the 'this' keyword

Will this calc function be defined once (put on the prototype chain for the 'obj' variable)? If not, then how can I get the calc function on the prototype chain so all instantiations of Obj will reference the same calc function?
I tried assigning the calc function to Obj.prototype.calc, but then when 'obj' is created, it can't find it in the creation process.
window.onload = function () {
var Obj = function (obj) {
var calc = function (o) {
for (p in o) {
if (o.hasOwnProperty(p) && typeof o[p] === 'function') {
o[p] = o[p]();
}
}
return o;
};
return calc(obj);
};
function test() {
var obj = new Obj({
a: 1,
b: 2,
c: function () {
return this.a + this.b;
},
d: function () {
return this.b * this.c;
}
});
window.console.log(obj.a); // 1
window.console.log(obj.b); // 2
window.console.log(obj.c); // 3
window.console.log(obj.d); // 6
}
test();
}
The purpose of the Obj constructor is creating an object literal type syntax when I define many versions of 'obj' but allowing the use of the 'this' keyword to calculate properties in terms of other properties in each object.
Here is the version with the prototype definition which doesn't work:
<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload = function () {
var Obj = function (obj) {
return calc(obj);
};
Obj.prototype.calc = function (o) {
for (p in o) {
if (o.hasOwnProperty(p) && typeof o[p] === 'function') {
o[p] = o[p]();
}
}
return o;
};
function test() {
var obj = new Obj({
a: 1,
b: 2,
c: function () {return this.a + this.b;},
d: function () {return this.b * this.c;}
});
window.console.log(obj.a);
window.console.log(obj.b);
window.console.log(obj.c);
window.console.log(obj.d);
}
test();
}
</script>
</head>
<body>
</body>
</html>
Will this calc function be defined once (put on the prototype chain for the 'obj' variable)?
No, it gets re-created every time your Obj function is called. (Also note that as Pointy, er, pointed out, you're falling prey to The Horror of Implicit Globals with your calc symbol.)
If not, then how can I get the calc function on the prototype chain so all instantiations of Obj will reference the same calc function?
By putting it there, and then using it from there:
Obj.prototype.calc = /* ...the function, use `this` rather than an argument... */;
and in Obj:
this.calc(); // No `return` needed
Simplified example:
var Foo = function(x, y) {
this.x = x;
this.y = y;
this.calc();
};
Foo.prototype.calc = function() {
this.z = this.x + this.y;
};
var f = new Foo(2, 3);
console.log(f.z); // "5"

javascript inheritance and instance variables

I'm trying to understand how inheritance works in JS. Suppose we have a class:
Class = function () {
this.A = 'A';
this.B = 'B';
};
and we are trying to extend it
SubClass = function () {};
SubClass.prototype = new Class();
Do I understance correctly that after inheritance properties A and B are common for all instances of SubClass, since they belong to it's prototype? If yes, how can Class be extended so that A and B do not be part of prototype?
UPD: note that Class uses A and B, so I can't declare them in SubClass.
Thank you in advance!
All I want is to make A and B be accessible and specific for each
"instance"
The typical way of doing this is to pass parameters and assign them to properties. Then you can use call to reference the super class. In other words:
function Person( name, age ) {
this.name = name;
this.age = age;
}
function Student( name, age, grade ) {
Person.call( this, name, age ); // call super-class with sub-class properties
this.grade = grade;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
var roger = new Student( 'Roger', 18, 'A+' );
You can use properties in parent class without defining:
Class = function () {
this.sum = function() {
return this.a+this.b;
}
};
SubClass = function () {
this.a = 5;
this.b = 6;
};
SubClass.prototype = new Class();
var z = new SubClass();
z.sum(); //11
Another way: Create function in prototype which creates your properties:
Class = function () {
this.makeAB = function() { //called with context of SubClass
this.A = 'A';
this.B = 'B';
}
};
SubClass = function () { this.makeAB() };
SubClass.prototype = new Class();
var z = new SubClass();
z.A = 'AAA';
z.B = 'BBB';
var z2 = new SubClass();
console.log(z)
console.log(z2)

JavaScript field Inheritance weird behaviour

function A(){
this.a = {};
this.b = 0;
this.Test = function(value){
this.a.x = value;
this.b = value;
};
}
function B(){}
B.prototype = new A;
var b1= (new B());
b1.Test(1);
var b2= (new B());
b2.Test(2);
log(b1.b == 1); //true
log(b2.b == 2); //true
log(b1.a.x == 1);//false x == 2
log(b2.a.x == 2);//true
Why are instances share field a?
This happens because the a object is shared across all instances of B (since the B prototype's is an instance of A).
A workaround would be to assign a new object in your Test method as an own property that shadows the one available on the prototype chain, for example:
function A(){
this.a = {};
this.b = 0;
this.Test = function(value){
this.a = {x: value}; // shadow the object on the prototype chain
this.b = value;
};
}
function B(){}
B.prototype = new A;
var b1= new B();
b1.Test(1);
var b2= new B();
b2.Test(2);
console.log(b1.b == 1); //true
console.log(b2.b == 2); //true
console.log(b1.a.x == 1);//true
console.log(b2.a.x == 2);//true

Categories