Em primeiro lugar, definiremos um método auxiliar usado para copiar as propriedades de um objeto para outro, substituindo as comuns:
function ex (destination, source) {
var p;
for (p in source) {
if (source.hasOwnProperty(p)) {
destination[p] = source[p];
}
}
return destination;
}
Vamos definir nosso principal método de extensão:
function extend (data, staticData) {
var parent = this,
child = function () {
if (data.initialize) {
data.initialize.apply(this, arguments);
} else {
parent.apply(this, arguments);
}
};
ex(child, parent);
if (staticData) {
ex(child, staticData);
}
if (!data) {
data = {};
}
child.prototype = ex(Object.create(parent.prototype), data);
child.prototype.constructor = child;
child.prototype.__super = parent.prototype;
return child;
}
A ideia é que esse método seja chamado na classe para se tornar a classe pai.
Ele tem dois parâmetros – data e staticData.
O parâmetro de dados é usado para passar campos de instância e métodos para a classe filha que pode substituir os pais.
O staticData é usado para definir campos e métodos de nÃvel de classe para a classe filha.
Vamos usar!
function Foo (a, b) {
this.a = a;
this.b = b;
}
Foo.prototype.c = function () {
return this.a + this.b
};
var foo = new Foo(2, 5);
console.log(foo.c());// 2+7
Agora é a hora da herança!
Foo.extend = extend;
Bar = Foo.extend({
initialize: function (a, b, d) {
this.__super.constructor(a, b);
this.d = d;
},
d: 8,
e: function () {
return this.a + this.b + this.d;
}
});
var bar = new Bar(3, 1, 9);
console.log(bar.c(), bar.e()); // 3+1=4, 3+1+9=13