Extend Already Defined Class In Javascript
Solution 1:
You want something like
┌──> Fuu.prototype
instances ──┤
└──> OtherClass.prototype
But that's not possible, because objects only have one [[Prototype]].
Therefore, you must achieve one of these:
instances ───> Fuu.prototype ───> OtherClass.prototype
instances ───> OtherClass.prototype ───> Fuu.prototype
So you must set the [[Prototype]] of one of those to be the other one. I will assume the first possibility.
There are two main ways to set the [[Prototype]]:
Object.create
, when creating the objectThe problem is that both
Fuu.prototype
andOtherClass.prototype
have been created already.However, you can create a new object with the right [[Prototype]] and assign the properties of the old one.
Since there may be non-enumerable properties, you must use
getOwnPropertyNames
. UsingdefineProperty
andgetOwnPropertyDescriptor
may also be a good idea, in case there are getters or setters.var old = Fuu.prototype, props = Object.getOwnPropertyNames(old); Fuu.prototype = Object.create(OtherClass.prototype); for(var i=0; i<props.length; ++i) Object.defineProperty( Fuu.prototype, props[i], Object.getOwnPropertyDescriptor(old, props[i]) );
setPrototypeOf
or__proto__
(ES6), once the object has been created:Object.setPrototypeOf(Fuu.prototype, OtherClass.prototype);
Fuu.prototype.__proto__ = OtherClass.prototype;
However, be aware that
Mutating the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of mutating prototypes [...] may extend to any code that has access to any object whose [[Prototype]] has been mutated. If you care about performance you should avoid mutating the [[Prototype]] of an object.
Solution 2:
I think the method you have suggested is probably the bet way to go. Is there a reason why you think it is wrong?
var old = Fuu.prototype;
Fuu.prototype = Object.create(OtherClass.prototype, {
constructor: {
value: Fuu,
enumerable: false,
writable: true,
configurable: true
}
});
var names = Object.getOwnPropertyNames(old);
for (var i = 0; i < names.length; i++) {
var name = names[i];
Fuu.prototype[name] = old[name];
}
The only thing I'd be concerned about is your constructor
method being overridden by the old version, and for your old prototype's prototype chain being lost; however you can do things to fix this.
Post a Comment for "Extend Already Defined Class In Javascript"