Need to know how to override the getters and setters by extending using prototypal inheritance
Following is an example to understand the issue
function A() {
this._loading = "Welcome";
}
Object.defineProperty(A.prototype, 'loading', {
get() {
return this._loading+" from A";
},
set(value) {
this._loading = value;
}
});
function B() {}
Object.defineProperty(B.prototype, 'loading', {
get() {
return this._loading+" from B";
},
set(value) {
this._loading = value;
}
});
var a=new A();
var b=new B();
b.__proto__=a; // Not sure if this is wrong. This assigns the whole prototype of A to B so that B is submerged
My expected result is b.loading should return me Welcome from B
Instead its returning Welcome from A
Help is appreciated.
Welcome to stackoverflow ;)
In Javascript you have different way to handle "inheritance". As you said, your implementation is not working because of the proto reassignation.
1. Overriding prototype
Usually it is considered bad practices to access prototype using __proto__
. In your case you are re-assigning the whole prototype of B, so it will just replace all prototype.
// Here you are overriding the prototype of "b"
b.__proto__=a;
// It refers to the prototype of a, so it the equivalent of calling a.loading
b.loading
2. Inherits from other prototype - ES5
function B() {
// Call the constructor of A giving the "B.this" context
A.call(this)
}
// Inherits from prototype of A
B.prototype = Object.create(A.prototype)
Object.defineProperty(B.prototype, 'loading', {
get() {
return this._loading+" from B";
}
});
// You won't need to instanciate A to inherits from it
const b = new B();
b.loading // "Welcome from B"
3. A step further
In a real world scenario you may want to inherits some properties from A, and override other properties in B. Because B inherits from A, you can call both methods from B.prototype and A.prototype.
function A() {
this._loading = "Welcome";
}
Object.defineProperty(A.prototype, "loadingA", {
get: function loading() {
return this._loading + " from A"
}
});
Object.defineProperty(A.prototype, "loading", {
get: function loading() {
return this._loading + " from A"
}
});
function B() {
A.call(this)
}
B.prototype = Object.create(A.prototype)
Object.defineProperty(B.prototype, 'loading', {
get() {
return this._loading+" from B";
}
});
var b = new B()
b.loading // Welcome from B
b.loadingA // Welcome from A
4. A second step further - ES6+
You may want to use ES6 class syntax sugar, it's less verbose and easier to understand ;)
class A {
constructor() {
this._loading = "Welcome"
}
get loading() {
return this._loading + " from A"
}
}
class B extends A {
get loading() {
return this._loading + " from B"
}
}
b.loading // Welcome from B
b.loadingA // Welcome from A