Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I heard that multiple inheritance is not supported in JavaScript.
Does the below example can be considered as Multiple Inheritance if no then can anyone please explain why...?
function A () {
this.a = 'a'
};
function B () {
this.b = 'b'
};
function AB () {
A.call(this);
B.call(this);
};
var obj = new AB();
console.dir(obj);
//Output: {a: "a", b: "b"}
Can the below example be considered Multiple Inheritance?
No
Can anyone please explain why?
Your AB (which I will call C from here on out) function doesn't actually extend A nor does it extend B:
function A () {
this.a = 'a';
}
function B () {
this.b = 'b';
}
function C () {
A.call(this);
B.call(this);
}
a = new A();
console.log('a is A', a instanceof A);
b = new B();
console.log('b is B', b instanceof B);
c = new C();
console.log('c is A', c instanceof A, 'c is B', c instanceof B);
You don't have any inheritance at all in that example. You do have function composition.
If you wanted to have inheritance, the C function would need to have a prototype that points to an instance of either A or B:
function A () {
this.a = 'a';
}
function B () {
this.b = 'b';
}
function C () {
A.call(this);
B.call(this);
}
C.prototype = new A();
//or
//C.prototype = new B();
a = new A();
console.log('a is A', a instanceof A);
b = new B();
console.log('b is B', b instanceof B);
c = new C();
console.log('c is A', c instanceof A, 'c is B', c instanceof B);
Note that because the C function has a single prototype you can only have single inheritance.
For object composition, it would be common to see a pattern along the lines of:
function A () {
this.a = 'a';
}
function B () {
this.b = 'b';
}
function C () {
this.a = new A();
this.b = new B();
}
a = new A();
console.log('a is A', a instanceof A);
b = new B();
console.log('b is B', b instanceof B);
c = new C();
console.log('c.a is A', c.a instanceof A, 'c.b is B', c.b instanceof B);
What you have done is called composition and it is often an alternative to multiple inheritance.
Here are some references that might help you
Prefer composition over inheritance?
https://softwareengineering.stackexchange.com/questions/134097/why-should-i-prefer-composition-over-inheritance
Related
How can I create a function that inherits from two functions and respects changes for their prototypes when the two base functions don't have an inheritance relationship?
The example demonstrates the behavior I want because c gets modifications to A.prototype and B.prototype.
function A() { }
function B() { }
B.prototype = Object.create(A.prototype);
function C() { }
C.prototype = Object.create(B.prototype);
A.prototype.foo = "foo";
B.prototype.bar = "bar";
var c = new C();
console.log(c.foo); //prints foo
console.log(c.bar); //prints bar
However, I don't have the luxury where B inherits from A.
function A() { }
function B() { }
function C() { }
C.prototype = //something that extends A and B even though B does not extend A.
A.prototype.foo = "foo";
B.prototype.bar = "bar";
var c = new C();
console.log(c.foo); //should print foo
console.log(c.bar); //should print bar
This is not possible.
Try using a mixin pattern, or have a property of C inherit from B and another property inherit from A.
Then access through these properties.
You could change your code to do something like this
C.prototype.perform = function (key) {
var args = Array.prototype.slice(arguments, 1);
if (key in this)
return this[key].apply(this, args);
if (key in B.prototype)
return B.prototype[key].apply(this, args);
if (key in A.prototype)
return A.prototype[key].apply(this, args);
undefined(); // throw meaningful error
}
C.prototype.get = function (key) {
if (key in this)
return this[key];
if (key in B.prototype)
return B.prototype[key];
if (key in A.prototype)
return A.prototype[key];
}
Then use it like
var c = new C();
c.perform('toString');
c.get('foo');
function A() {
this.a = 'this is a';
var b = 'this is b';
}
function B() {
var self = this;
this.c = 'this is c';
var d = 'this is d';
// a: undefined, b: undefined, c: this is c, d: this is d
$("#txt1").text('a: ' + A.a + ', b: ' + b + ', c: ' + this.c + ', d: ' + d);
C();
function C() {
// this.c is not defined here
// a: undefined, b: undefined, c: this is c, d: this is d
$("#txt2").text('a: ' + A.a + ', b: ' + b + ', c: ' + self.c + ', d: ' + d);
}
}
B.prototype = new A();
var b = new B();
Is it possible for class B and inner function C to get variable a and b?
Fiddle file is here: http://jsfiddle.net/vTUqc/5/
You can get a in B, using this.a, since the prototype of B is an instance of A. You can also get a in C, using self.a:
function A() {
this.a = 'this is a'; // This is accessible to any instance of A
var b = 'this is b'; // This is not accessible outside the scope of the function
}
function B() {
var self = this;
alert(this.a); // Alerts 'this is a'
C(); // Also alerts 'this is a'
function C() {
alert(self.a);
}
}
B.prototype = new A();
new B();
You can't get b directly on the other hand. If you want to access it, you could use a function that returns its value:
function A() {
this.a = 'this is a';
var b = 'this is b';
this.returnb = function(){
return b;
}
}
Now b is accessible to instances of A via (new A()).returnb()
In javascript how can I know which object I inehrit?
for example
function a() {
this.c = 1;
}
function b() {
this.d = 2;
}
b.prototype = new a();
How can I check that b inherit from a?
Thank you.
Use the instanceof operator:
//capital letters indicate function should be used as a constructor
function A() {...}
function B() {...}
B.prototype = new A();
var a,
b;
a = new A();
b = new B();
console.log(a instanceof A); //true
console.log(a instanceof B); //false
console.log(b instanceof A); //true
console.log(b instanceof B); //true
console.log(B.prototype instanceof A); //true
Try this
b.prototype.constructor.name
Working example: http://jsfiddle.net/psrcK/
Use the constructor property of b.prototype or any instance of b.
function a(){
this.c=1;
}
function b(){
this.d=2;
}
b.prototype=new a();
x = new b()
if(x.constructor == a){
// x (instance of b) is inherited from a
}
of you probably want instanceOf.
if (b instanceOf a) {
console.log("b is instance a")
}
This also has the advantage of walking the whole prototype chain so it does not matter if it is a parent, grandparent, etc
Is there a way in JavaScript to inherit from a constructor function that returns a function? For example:
var A = function() {
return function(input) {
// do stuff
};
};
var B = function() {};
B.prototype = new A();
var b = new B();
Thanks
By returning a function from your constructor, you're not creating an instance of A, but rather an instance of the function. Therefore, inheritance will not work.
var A = function() { return function(input) {}; };
var a = new A();
>>> typeof a;
"function"
var A = function() {};
var a = new A();
>>> typeof a;
"object"
If you need B to inherit the returned function from A, you should set it as a method of A, either locally or in the prototype chain, and pass it that way.
var A = function() {
this.method = function(input) {}
};
var B = function() {}
B.prototype = new A();
var b = new B();
>>> b.method
'function(input) { }'
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