Olvídate de todo el conocimiento orientado a objetos que aprendiste antes. Solo considere la situación de las carreras aquí. Sí, es carreras.
Recientemente estoy viendo 24 horas de Le Mans, un evento popular en Francia. El auto más rápido se llama prototipo Le Mans. Aunque estos autos están hechos por fabricantes como "Audi" o "Peugeot", no son el tipo de autos que ves en la calle o en la carretera. Están hechos específicamente para eventos de resistencia de alta velocidad.
El fabricante invierte grandes cantidades de dinero para desarrollar, diseñar y fabricar estos autos prototipo, y los ingenieros siempre intentan hacer este proyecto al extremo. Realizaron varios experimentos sobre aleaciones, biocombustibles, tecnología de frenado, composición compuesta y características de seguridad de los neumáticos. Con el tiempo, algunas de las técnicas en estos experimentos se han mejorado repetidamente e ingresaron a la línea de productos de los vehículos principales. Es posible que parte de la tecnología en el vehículo que esté conduciendo se debutó en el prototipo de carreras.
También puede decir que estos vehículos convencionales heredan los prototipos técnicos de los autos de carreras.
Hasta ahora, tenemos la base para discutir el prototipo y los problemas de herencia en JavaScript. Si bien no es tan bueno como el patrón de herencia clásico que conoces en C ++, Java o C#, es igual de poderoso y potencialmente más flexible.
JavaScript está lleno de objetos, que se refieren a los objetos en el sentido tradicional, es decir, "una entidad única que contiene estado y comportamiento". Por ejemplo, una matriz en JavaScript es un objeto que contiene varios valores y contiene métodos Push, Reverse y POP.
var myArray = [1, 2]; myArray.push (3); myArray.Reverse (); myArray.pop (); var longitud = myArray.length;
Ahora la pregunta es, ¿de dónde viene el empuje? Los lenguajes estáticos que mencionamos anteriormente usan "sintaxis de clase" para definir la estructura de los objetos, pero JavaScript es un lenguaje sin "sintaxis de clase" y no puede definir cada objeto de matriz usando la sintaxis de la matriz "clase". Y debido a que JavaScript es un lenguaje dinámico, podemos colocar métodos en los objetos como realmente los necesitamos. Por ejemplo, el siguiente código define un objeto de punto utilizado para representar un punto en el espacio bidimensional, y también define un método ADD.
Var Point = {x: 10, y: 5, add: function (otherpoint) {this.x += otherpoint.x; this.y += OtherPoint.y; }};Sin embargo, las prácticas anteriores no son muy escalables. Necesitamos asegurarnos de que cada objeto de punto contenga un método ADD, y también queremos que todos los objetos de punto compartan la implementación del mismo método ADD, en lugar de agregar manualmente este método a cada objeto de punto. Aquí es donde entra en juego el prototipo.
En JavaScript, cada objeto permanece oculto, una referencia a otro objeto, también conocido como prototipo. La matriz que creamos antes hace referencia a un objeto prototipo, y también los objetos de punto que creamos nosotros mismos. Como se mencionó anteriormente, las referencias de prototipo están ocultas, pero también hay implementaciones de ECMAScript (el nombre oficial de JavaScript) que pueden acceder a esta referencia de prototipo a través del atributo __proto__ de un objeto (como Google Chrome). Conceptualmente, podemos tratar los objetos como relaciones similares a las representadas en la Figura 1-Prototipo.
Figura 1
Mirando hacia el futuro, los desarrolladores podrán usar la función Object.getProTotypeOf en lugar del atributo __proto__ para obtener referencias al prototipo de objeto. Al momento de escribir este artículo, la función Object.getProtypeOf ya se puede usar en los navegadores Google Chrome, Firefox e IE9. Más navegadores implementarán esta función en el futuro porque ya es parte del estándar de ECMAScript. Podemos usar el siguiente código para demostrar que los objetos myArray y DOT que creamos se refieren a dos objetos prototipos diferentes.
Para el resto de este artículo, utilizaré las funciones __proto__ y object.getProTotypeOf, principalmente porque __proto__ es más fácil de identificar en gráficos y oraciones. Debe recordarse que él (__proto__) no es el estándar, y la función Object.getProtypeOf es el método recomendado para ver los prototipos de objetos.
¿Qué hace que el prototipo sea tan especial?
No hemos respondido esta pregunta: ¿De dónde viene Push en una matriz? La respuesta es: proviene del objeto MyArray Prototype. La Figura 2 es una captura de pantalla del depurador del guión en Chrome. Hemos llamado el método Object.getPrototypeOf para ver el objeto prototipo de MyArray.
Figura 2
Tenga en cuenta que hay muchos métodos en el objeto prototipo de MyArray, incluidos los llamados métodos Push, POP e inverso en ejemplos de código. Por lo tanto, el método push incluye el objeto prototipo, pero ¿cómo se refiere el método myArray?
myArray.push (3);
El primer paso para comprender cómo funciona es darse cuenta de que el prototipo no es especial. El prototipo es solo un objeto normal. Puede agregar métodos, propiedades al prototipo y tratarlos como otros objetos JavaScript. Sin embargo, para aplicar la declaración de "cerdo" en la novela "granja de animales" de George Orwell, todos los objetos deberían ser iguales, pero algunos objetos (aquellos que siguen las reglas) son más iguales que otros.
Los objetos prototipo en JavaScript son realmente especiales porque siguen las siguientes reglas. Cuando le decimos a JavaScript que queremos llamar al método de empuje de un objeto, o leer la propiedad X del objeto, el tiempo de ejecución primero buscará el objeto en sí. Si el tiempo de ejecución no puede encontrar lo que quiere, sigue el prototipo de referencia y objetos __proto__ para buscar al miembro. Cuando llamamos al método Push MyArray, JavaScript no encuentra el método de push en el objeto MyArray, sino en el objeto prototipo de MyArray, por lo que JavaScript llama a este método (ver Figura 3).
Figura 3
El comportamiento descrito anteriormente se refiere a un objeto que hereda cualquier método o propiedad en el prototipo. En JavaScript, la herencia se logra en realidad sin usar sintaxis de clase. Al igual que un automóvil que hereda la tecnología correspondiente de un prototipo de carreras, un objeto JavaScript también puede heredar las características funcionales desde un objeto prototipo.
La Figura 3 también muestra que cada objeto de matriz también puede mantener su propio estado y miembros. Al solicitar el atributo de longitud de MyArray, JavaScript obtendrá el valor del atributo de longitud en MyArray sin leer el valor correspondiente en el prototipo. Podemos "sobrescribir" el método de empuje agregando un método como empujar al objeto. Esto ocultará efectivamente la implementación del método push en el prototipo.
La verdadera magia de los prototipos en JavaScript es cómo múltiples objetos mantienen referencias al mismo objeto prototipo. Por ejemplo, si creamos dos matrices como esta:
var myArray = [1, 2]; var yourArray = [4, 5, 6];
Luego, estas dos matrices compartirán el mismo objeto prototipo, y el siguiente código se evalúa como verdadero:
Object.getPrototypeOf (myArray) === Object.getPrototypeOf (yourArray);
Si nos referimos al método Push en dos objetos de matriz, JavaScript buscará el método Push compartido en el prototipo.
Figura 4
Los objetos prototipos en JavaScript proporcionan funciones de herencia, y al mismo tiempo, se implementa el intercambio de este método. El prototipo también está encadenado. En otras palabras, debido a que un objeto prototipo es solo un objeto, se puede mantener un objeto prototipo en una referencia a otro objeto prototipo. Si vuelve a visitar la Figura 2, puede ver que la propiedad __proto__ del prototipo es un valor no nulo que apunta a otro prototipo. Cuando JavaScript busca miembros como el método Push, verifica cada objeto a lo largo de la cadena de referencia del prototipo hasta que se encuentra, o alcanza el final de la cadena prototipo. Las cadenas prototipo abren una ruta flexible para la herencia y el intercambio.
La siguiente pregunta que podría hacer es: ¿Cómo configuro las referencias prototipo a esos objetos personalizados? Por ejemplo, el objeto de punto utilizado anteriormente, ¿cómo puedo agregar el método Agregar al objeto prototipo y heredar el método desde múltiples objetos de punto? Antes de responder a esta pregunta, debemos mirar las funciones.
Las funciones en JavaScript también son objetos. Tal declaración trae varios resultados importantes, y no cubriremos todos los asuntos en este artículo. Entre ellos, la capacidad de asignar una función a una variable y pasar una función como parámetro a otra función constituye el paradigma básico de la expresión de programación de JavaScript moderna.
A lo que debemos prestar atención es que la función en sí es un objeto, por lo que la función puede tener sus propios métodos, propiedades y referencia a un objeto prototipo. Discutamos el significado del siguiente código.
// Esto devolverá verdadero: typeof (array) === "función" // dicha expresión también es: object.getPrototypeOf (array) === objeto.getPrototypeOf (function () {}) // dicha expresión es la misma: array.prototype! = NullLa primera línea en el código demuestra que la matriz en JavaScript es una función. Veremos cómo llamar a la función de matriz para crear un nuevo objeto de matriz. La siguiente línea de código demuestra que el objeto de matriz usa el mismo prototipo que cualquier otro objeto de función, al igual que vemos que el mismo prototipo se comparte entre los objetos de matriz. La última línea de código demuestra que la función de matriz tiene una propiedad prototipo, y esta propiedad prototipo apunta a un objeto válido. Esta propiedad prototipo es muy importante.
Cada objeto de función en JavaScript tiene una propiedad prototipo. Nunca confunda el atributo __proto__ de esta propiedad prototipo. Son de diferentes propósitos, ni apuntan al mismo objeto.
// return trueObject.getPrototypeOf (Array)! = Array.Prototype
Array .__ Proto__ proporciona un prototipo de matriz. Trátelo como un objeto heredado por la función de matriz.
Array.protoype proporciona objetos prototipo para todas las matrices. Es decir, proporciona objetos prototipo de objetos de matriz como MyArray, y también contiene métodos que todas las matrices heredarán. Podemos escribir algún código para probar este hecho.
// truearray.prototype == object.getPrototypeOf (myArray) // también es truearray.prototype == object.getPrototypeOf (yourArray);
También podemos usar este nuevo conocimiento para volver a pintar el diagrama anterior.
Figura 5
Según lo que sabe, imagine el proceso de crear un nuevo objeto y hacer que el nuevo objeto se comporte como una matriz. Una forma es usar el siguiente código.
// Crear un nuevo objeto vacío var o = {}; // heredado del mismo prototipo, un objeto de matriz o .__ proto__ = array.prototype; // Ahora podemos llamar a cualquier método de la matriz ... o.push (3);Aunque este código es interesante y funciona, el problema es que no todos los entornos de JavaScript admiten propiedades de objetos __proto__ escritos. Afortunadamente, JavaScript tiene un mecanismo estándar para crear objetos. Solo requiere un operador para crear nuevos objetos y establecer la referencia __proto__ del nuevo objeto, ese es el "nuevo" operador.
var o = new Array (); O.Push (3);
El nuevo operador en JavaScript tiene tres tareas básicas. Primero, crea un nuevo objeto vacío. A continuación, establecerá la propiedad __proto__ del nuevo objeto para que coincida con las propiedades prototipo de la función llamada. Finalmente, el operador llama a la función, pasando el nuevo objeto como una referencia "esta". Si desea extender las últimas dos líneas de código, se convertirá en la siguiente situación:
var o = {}; o .__ proto__ = array.prototype; array.call (o); o.push (3);El método de llamadas de la función le permite especificar el objeto hecho referido por "esto" dentro de la función al llamar a la función. Por supuesto, el autor de la función necesita implementar dicha función en este caso. Una vez que el autor crea tal función, se puede llamar constructor.
Constructor
Los constructores son los mismos que las funciones ordinarias, pero tienen las siguientes dos propiedades especiales.
La matriz es un ejemplo de un constructor. La función de matriz debe usarse con el nuevo operador, y la letra de matriz inicial está capitalizada. JavaScript incluye la matriz como una función incorporada, y cualquiera puede escribir su propio constructor. De hecho, finalmente podemos escribir un constructor para los objetos de punto creados anteriormente.
Var Point = function (x, y) {this.x = x; this.y = y; this.Add = function (OtherPoint) {this.x += OtherPoint.x; this.y += OtherPoint.y; }} var p1 = nuevo punto (3, 4); var p2 = nuevo punto (8, 6); p1.add (p2);En el código anterior, utilizamos el nuevo operador y la función puntual para construir un objeto de punto, que tiene los atributos X e Y y un método ADD. Puede imaginar el resultado final como se muestra en la Figura 6.
Figura 6
El problema ahora es que todavía hay un método ADD separado en cada uno de nuestros objetos de puntos. Usando el prototipo y la herencia que aprendimos, preferiríamos transferir el método Agregar del objeto punto desde cada instancia de punto a punto.prototype. Para lograr el efecto de heredar el método ADD, todo lo que necesitamos hacer es modificar el objeto Point.prototype.
Var Point = function (x, y) {this.x = x; this.y = y;} Point.prototype.add = function (OtherPoint) {this.x += OtherPoint.x; this.y += OtherPoint.y;} var p1 = nuevo punto (3, 4); var p2 = nuevo punto (8, 6); p1.add (p2);¡La misión está hecha! ¡Acabamos de completar el modo de herencia del prototipo en JavaScript!
Figura 7
Resumir
Espero que este artículo te ayude a descubrir el misterio de los conceptos prototipo de JavaScript. Lo que vi al principio fue cómo el prototipo permitió que un objeto heredara las funciones de otros objetos, y luego vi cómo combinar el nuevo operador y el constructor para construir el objeto. Lo que se menciona aquí es solo el primer paso para desbloquear la potencia y la flexibilidad del prototipo de objeto. Este artículo lo alienta a descubrir y aprender nueva información sobre prototipos e idiomas de JavaScript para usted.
Además, conduzca cuidadosamente. Nunca sabrá qué tecnología (defectuosa) estos vehículos que viajan en la carretera heredarán de sus prototipos.
Enlace original: Script Junkie Traducción: Bole en línea - Emje