JavaScript: ¿Para qué se usan .extend y .prototype?
122
Soy relativamente nuevo en JavaScript y sigo viendo .extend y .prototype en las bibliotecas de terceros que estoy usando. Pensé que tenía que ver con la biblioteca Prototype javascript, pero estoy empezando a pensar que ese no es el caso. ¿Para qué se usan estos?
La herencia de Javascript se basa en prototipos, por lo que puede extender los prototipos de objetos como Fecha, Matemáticas e incluso sus propios objetos personalizados.
En el fragmento anterior, defino un método para todos los objetos Date (ya existentes y todos los nuevos).
extend Por lo general, es una función de alto nivel que copia el prototipo de una nueva subclase que desea extender desde la clase base.
Entonces puedes hacer algo como:
extend(Fighter,Human)
Y el Fighterconstructor / objeto heredará el prototipo de Human, por lo que si se define como métodos livey dieel Humanentonces Fightertambién herede esos.
Aclaración actualizada:
"función de alto nivel", que significa .extend, no está integrado, sino que a menudo lo proporciona una biblioteca como jQuery o Prototype.
El significado de "función de alto nivel" .extendno está integrado, pero a menudo lo proporciona una biblioteca como jQuery o Prototype.
visum
13
Agregaría
1
@meder: debe agregar un comentario visum en su respuesta. :)
Manish Gupta
9
En la programación moderna de Javascript, es habitual tratar los objetos globales y nativos como elementos de un baño público; No puede evitar entrar allí, pero debe tratar de minimizar el contacto con las superficies. Esto se debe a que changing the native objects can break other developer's assumptions of these objects,conduce a errores de JavaScript que a menudo pueden costar muchas horas rastrear. La oración principal de esta respuesta parece tergiversar esta valiosa práctica de JavaScript.
.prototype se refiere a la "plantilla" (si quiere llamarlo así) de un objeto, por lo que al agregar métodos al prototipo de un objeto (lo ve mucho en las bibliotecas para agregar a String, Date, Math o incluso Function) esos métodos se agregan a cada nueva instancia de ese objeto.
La herencia de Javascript parece ser como un debate abierto en todas partes. Se le puede llamar "El curioso caso del lenguaje Javascript".
La idea es que haya una clase base y luego extienda la clase base para obtener una característica similar a la herencia (no completamente, pero aún así).
La idea es entender qué significa realmente un prototipo. No lo entendí hasta que vi el código de John Resig (cerca de lo que jQuery.extendhace) escribió un fragmento de código que lo hace y afirma que las bibliotecas base2 y prototipo fueron la fuente de inspiración.
Aquí está el 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;};})();
Hay tres partes que están haciendo el trabajo. Primero, recorre las propiedades y las agrega a la instancia. Después de eso, crea un constructor para luego agregarlo al objeto. Ahora, las líneas clave son:
// Populate our constructed prototype objectClass.prototype = prototype;// Enforce the constructor to be what we expectClass.prototype.constructor=Class;
Primero apunta el Class.prototypeprototipo deseado. Ahora, todo el objeto ha cambiado, lo que significa que debe forzar el diseño a su propio diseño.
Y el ejemplo de uso:
varCar=Class.Extend({
setColor:function(clr){
color = clr;}});var volvo =Car.Extend({
getColor:function(){return color;}});
Algunas extendfunciones en bibliotecas de terceros son más complejas que otras. Knockout.js, por ejemplo, contiene uno mínimamente simple que no tiene algunas de las comprobaciones que tiene jQuery:
function extend(target, source){if(source){for(var prop in source){if(source.hasOwnProperty(prop)){
target[prop]= source[prop];}}}return target;}
.extends() crear una clase que es hija de otra clase. Detrás de escena
Child.prototype.__proto__establece su valor para Parent.prototype que los métodos se hereden.
.extend
no está integrado, pero a menudo lo proporciona una biblioteca como jQuery o Prototype.changing the native objects can break other developer's assumptions of these objects,
conduce a errores de JavaScript que a menudo pueden costar muchas horas rastrear. La oración principal de esta respuesta parece tergiversar esta valiosa práctica de JavaScript..extend()
es agregado por muchas bibliotecas de terceros para facilitar la creación de objetos a partir de otros objetos. Consulte http://api.jquery.com/jQuery.extend/ o http://www.prototypejs.org/api/object/extend para ver algunos ejemplos..prototype
se refiere a la "plantilla" (si quiere llamarlo así) de un objeto, por lo que al agregar métodos al prototipo de un objeto (lo ve mucho en las bibliotecas para agregar a String, Date, Math o incluso Function) esos métodos se agregan a cada nueva instancia de ese objeto.fuente
El
extend
método, por ejemplo, en jQuery o PrototypeJS , copia todas las propiedades del origen al objeto de destino.Ahora sobre la
prototype
propiedad, es un miembro de objetos de función, es parte del núcleo del lenguaje.Cualquier función se puede utilizar como constructor , para crear nuevas instancias de objeto. Todas las funciones tienen esta
prototype
propiedad.Cuando utiliza el
new
operador con en un objeto de función, se creará un nuevo objeto y heredará de su constructorprototype
.Por ejemplo:
fuente
La herencia de Javascript parece ser como un debate abierto en todas partes. Se le puede llamar "El curioso caso del lenguaje Javascript".
La idea es que haya una clase base y luego extienda la clase base para obtener una característica similar a la herencia (no completamente, pero aún así).
La idea es entender qué significa realmente un prototipo. No lo entendí hasta que vi el código de John Resig (cerca de lo que
jQuery.extend
hace) escribió un fragmento de código que lo hace y afirma que las bibliotecas base2 y prototipo fueron la fuente de inspiración.Aquí está el código.
Hay tres partes que están haciendo el trabajo. Primero, recorre las propiedades y las agrega a la instancia. Después de eso, crea un constructor para luego agregarlo al objeto. Ahora, las líneas clave son:
Primero apunta el
Class.prototype
prototipo deseado. Ahora, todo el objeto ha cambiado, lo que significa que debe forzar el diseño a su propio diseño.Y el ejemplo de uso:
Lea más sobre esto aquí en Herencia de Javascript por la publicación de John Resig .
fuente
Algunas
extend
funciones en bibliotecas de terceros son más complejas que otras. Knockout.js, por ejemplo, contiene uno mínimamente simple que no tiene algunas de las comprobaciones que tiene jQuery:fuente
.extends()
crear una clase que es hija de otra clase.Detrás de escena
Child.prototype.__proto__
establece su valor paraParent.prototype
que los métodos se hereden.
.prototype
heredar características de uno a otro..__proto__
es un getter / setter para Prototype.fuente