Respostas:
A herança do Javascript é baseada em protótipo; portanto, você amplia os protótipos de objetos como Data, Matemática e até os seus próprios personalizados.
Date.prototype.lol = function() {
alert('hi');
};
( new Date ).lol() // alert message
No trecho acima, defino um método para todos os objetos Date (já existentes e todos os novos).
extend
geralmente é uma função de alto nível que copia o protótipo de uma nova subclasse que você deseja estender da classe base.
Então você pode fazer algo como:
extend( Fighter, Human )
E o Fighter
construtor / object herdarão o protótipo Human
, por isso, se você definir métodos, como live
e die
em Human
seguida, Fighter
também herdará aqueles.
Esclarecimentos atualizados:
"função de alto nível", significando .extend não é incorporado, mas geralmente é fornecido por uma biblioteca como jQuery ou Prototype.
changing the native objects can break other developer's assumptions of these objects,
leva a erros de javascript, que geralmente custam muitas horas para serem rastreados. A frase principal desta resposta parece deturpar essa valiosa prática de javascript.
.extend()
é adicionado por muitas bibliotecas de terceiros para facilitar a criação de objetos a partir de outros objetos. Consulte http://api.jquery.com/jQuery.extend/ ou http://www.prototypejs.org/api/object/extend para alguns exemplos.
.prototype
refere-se ao "modelo" (se você quiser chamá-lo assim) de um objeto, portanto, adicionando métodos ao protótipo de um objeto (você vê muito isso nas bibliotecas para adicionar a String, Data, Matemática ou até Função) esses métodos são adicionados a cada nova instância desse objeto.
O extend
método, por exemplo, em jQuery ou PrototypeJS , copia todas as propriedades da origem para o objeto de destino.
Agora, sobre a prototype
propriedade, ela é um membro dos objetos de função, faz parte do núcleo da linguagem.
Qualquer função pode ser usada como construtor , para criar novas instâncias de objetos. Todas as funções têm essa prototype
propriedade.
Quando você usa o new
operador com um objeto de função, um novo objeto será criado e herdado de seu construtor prototype
.
Por exemplo:
function Foo () {
}
Foo.prototype.bar = true;
var foo = new Foo();
foo.bar; // true
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true
A herança do Javascript parece ser um debate aberto em todos os lugares. Pode ser chamado "O curioso caso da linguagem Javascript".
A idéia é que exista uma classe base e você a estenda para obter um recurso semelhante a uma herança (não completamente, mas ainda).
A idéia é entender o que realmente significa protótipo. Eu não o comprei até que vi o código de John Resig (próximo ao que jQuery.extend
faz) escreveu um pedaço de código que o faz e ele afirma que as bibliotecas base2 e protótipo eram a fonte de inspiração.
Aqui está o código.
/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function(){
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function(){};
// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
Existem três partes que estão fazendo o trabalho. Primeiro, você percorre as propriedades e as adiciona à instância. Depois disso, você cria um construtor para ser adicionado posteriormente ao objeto. Agora, as linhas principais são:
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
Você primeiro aponta Class.prototype
para o protótipo desejado. Agora, todo o objeto mudou, o que significa que você precisa forçar o layout de volta ao seu próprio.
E o exemplo de uso:
var Car = Class.Extend({
setColor: function(clr){
color = clr;
}
});
var volvo = Car.Extend({
getColor: function () {
return color;
}
});
Leia mais sobre isso aqui na Javascript Inheritance da publicação de John Resig .
Algumas extend
funções em bibliotecas de terceiros são mais complexas que outras. O Knockout.js, por exemplo, contém um minimamente simples que não possui algumas das verificações feitas pelo jQuery:
function extend(target, source) {
if (source) {
for(var prop in source) {
if(source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
.extends()
crie uma classe que é filha de outra classe. Child.prototype.__proto__
define seu valor para Parent.prototype
.prototype
herdar recursos de um para outro..__proto__
é um getter / setter para Prototype.
.extend
não é incorporado, mas geralmente é fornecido por uma biblioteca como jQuery ou Prototype.