JavaScript: Para que são utilizados o .extend e o .prototype?
122
Sou relativamente novo em JavaScript e continuo vendo .extend e .prototype em bibliotecas de terceiros que estou usando. Eu pensei que tinha a ver com a biblioteca javascript Prototype, mas estou começando a pensar que não é o caso. Para que são usados?
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.
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 Fighterconstrutor / object herdarão o protótipo Human, por isso, se você definir métodos, como livee dieem Humanseguida, Fightertambé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.
O significado de "função de alto nível" .extendnão é incorporado, mas geralmente é fornecido por uma biblioteca como jQuery ou Prototype.
141313 visum
13
Gostaria de acrescentar que não é sugerido para estender os protótipos de objetos nativos em JS
framp
1
@ medidor - você deve adicionar um comentário visum em sua resposta. :)
Manish Gupta
9
Na programação Javascript moderna, é habitual tratar objetos globais e nativos como elementos de um banheiro público; você não pode evitar entrar lá, mas tente minimizar o contato com as superfícies. Isso ocorre porque 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.
.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.
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.extendfaz) 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 classClass.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 =newthis();
initializing =false;// Copy the properties over onto the new prototypefor(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){returnfunction(){var tmp =this._super;// Add a new ._super() method that is the same method// but on the super-classthis._super = _super[name];// The method only need to be bound temporarily, so we// remove it when we're done executingvar ret = fn.apply(this, arguments);this._super = tmp;return ret;};})(name, prop[name]):
prop[name];}// The dummy class constructorfunctionClass(){// All construction is actually done in the init methodif(!initializing &&this.init )this.init.apply(this, arguments);}// Populate our constructed prototype objectClass.prototype = prototype;// Enforce the constructor to be what we expectClass.prototype.constructor=Class;// And make this class extendableClass.extend = arguments.callee;returnClass;};})();
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 objectClass.prototype = prototype;// Enforce the constructor to be what we expectClass.prototype.constructor=Class;
Você primeiro aponta Class.prototypepara 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:
varCar=Class.Extend({
setColor:function(clr){
color = clr;}});var volvo =Car.Extend({
getColor:function(){return color;}});
Algumas extendfunçõ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. nos bastidores
Child.prototype.__proto__define seu valor para Parent.prototype que os métodos sejam herdados.
.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.fonte
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 construtorprototype
.Por exemplo:
fonte
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.
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:
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:
Leia mais sobre isso aqui na Javascript Inheritance da publicação de John Resig .
fonte
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:fonte
.extends()
crie uma classe que é filha de outra classe.nos bastidores
Child.prototype.__proto__
define seu valor paraParent.prototype
que os métodos sejam herdados.
.prototype
herdar recursos de um para outro..__proto__
é um getter / setter para Prototype.fonte