eredità JavaScript da più oggetti
-
13-10-2019 - |
Domanda
Non sto molto bene con l'ereditarietà aquainted javascript, e sto cercando di fare uno ereditare da un altro oggetto, e definire i propri metodi:
function Foo() {}
Foo.prototype = {
getColor: function () {return this.color;},
};
function FooB() {}
FooB.prototype = new Foo();
FooB.prototype = {
/* other methods here */
};
var x = new FooB().getColor();
Tuttavia, il secondo sovrascrive il primo (FooB.prototype = new Foo() is cancelled out
). C'è un modo per risolvere questo problema, o sto andando nella direzione sbagliata?
Grazie in anticipo, mi spiace per qualsiasi terminologia male.
Soluzione
Ogni oggetto può avere solo un prototipo, quindi se si desidera aggiungere al prototipo dopo aver ereditato (la copia), è necessario espanderla invece di assegnare un nuovo prototipo. Esempio:
function Foo() {}
Foo.prototype = {
x: function(){ alert('x'); },
y: function(){ alert('y'); }
};
function Foo2() {}
Foo2.prototype = new Foo();
Foo2.prototype.z = function() { alert('z'); };
var a = new Foo();
a.x();
a.y();
var b = new Foo2();
b.x();
b.y();
b.z();
Altri suggerimenti
Una soluzione potrebbe essere:
function FooB() {}
var p = new Foo();
p.methodA = function(){...}
p.methodB = function(){...}
p.methodC = function(){...}
...
FooB.prototype = p;
Aggiornamento: Per quanto riguarda l'espansione con un oggetto esistente. È sempre possibile copiare le proprietà esistenti di un oggetto a un altro:
FooB.prototype = new Foo();
var proto = {
/*...*/
};
for(var prop in proto) {
FooB.prototype[prop] = proto[prop];
}
Finché proto
è un oggetto "normale" (cioè che non eredita da un altro oggetto) è soddisfacente. In caso contrario, si potrebbe desiderare di aggiungere if(proto.hasOwnProperty(prop))
aggiungere solo le proprietà non-ereditate.
È possibile utilizzare una funzione di extend
che copia i nuovi membri all'oggetto prototipo.
function FooB() {}
FooB.prototype = new FooA();
extend(FooB.prototype, {
/* other methods here */
});
estendere
/**
* Copies members from an object to another object.
* @param {Object} target the object to be copied onto
* @param {Object} source the object to copy from
* @param {Boolean} deep whether the copy is deep or shallow
*/
function extend(target, source, deep) {
for (var i in source) {
if (deep || Object.hasOwnProperty.call(source, i)) {
target[i] = source[i];
}
}
return target;
}