Función Prototipo Propiedad

los prototipo La propiedad es un objeto creado por JavaScript para cada Función() ejemplo. Específicamente, vincula instancias de objetos creadas con el nuevo palabra clave de nuevo a la función constructora que los creó. Esto se hace para que las instancias puedan compartir o heredar métodos y propiedades comunes. Es importante destacar que el intercambio se produce durante la búsqueda de propiedades. Recuerde desde el primer artículo, que cada vez que busque o acceda a una propiedad de un objeto, se buscará la propiedad tanto en el objeto como en la cadena de prototipos..

Se crea un objeto prototipo para cada función, independientemente de si tiene la intención de utilizar esa función como constructor.

En el siguiente código, construyo un array desde el Formación() constructor, y luego invoco el unirse() método.

Muestra: sample118.html

 

los unirse() método no se define como una propiedad de la myArray instancia de objeto, pero de alguna manera tenemos acceso a unirse() como si fuese. Este método se define en algún lugar, pero ¿dónde? Bueno, se define como una propiedad de la Formación() Propiedad prototipo del constructor. Ya que unirse() no se encuentra dentro de la instancia de objeto de matriz, JavaScript busca en la cadena de prototipos un método llamado unirse().

Bien, entonces, ¿por qué se hacen las cosas de esta manera? Realmente, se trata de eficiencia y reutilización. ¿Por qué todas las instancias de matriz creadas a partir de la función de constructor de matriz tienen una definición única? unirse() método cuando unirse() siempre funciona de la misma manera? Tiene más sentido para todas las matrices aprovechar el mismo unirse() Funciona sin tener que crear una nueva instancia de la función para cada instancia de matriz.

Esta eficiencia de la que hablamos es posible gracias a la prototipo propiedad, vinculación de prototipo y la cadena de búsqueda de prototipo. En este artículo, desglosamos estos atributos a menudo confusos de la herencia prototípica. Pero a decir verdad, estaría mejor si simplemente memorizara la mecánica de cómo funciona realmente la jerarquía de la cadena. Consulte el primer artículo si necesita una actualización sobre cómo se resuelven los valores de propiedad.


Por qué preocuparse por la prototipo Propiedad?

Usted debe preocuparse por la prototipo propiedad por cuatro razones.

Razón 1

La primera razón es que las propiedades constructoras nativas utilizan la propiedad prototipo (Objeto(), Formación(), Función(), etc.) para permitir que las instancias del constructor hereden propiedades y métodos. Es el mecanismo que usa JavaScript para permitir que las instancias de objetos hereden propiedades y métodos de las funciones del constructor. prototipo propiedad. Si desea comprender mejor JavaScript, necesita comprender cómo el propio JavaScript aprovecha la prototipo objeto.

Razón 2

Al crear funciones de constructor definidas por el usuario, puede organizar la herencia de la misma manera que lo hacen los objetos nativos de JavaScript. Pero primero tienes que aprender cómo funciona..

Razón 3

Puede que realmente no te guste la herencia prototípica o prefieras otro patrón para la herencia de objetos, pero la realidad es que algún día tendrás que editar o administrar el código de otra persona que pensaba que la herencia prototípica eran las rodillas de la abeja. Cuando esto suceda, deberías saber cómo funciona la herencia prototípica, y cómo pueden replicarla los desarrolladores que hacen uso de las funciones de constructor personalizadas..

Razón 4

Al utilizar la herencia prototípica, puede crear instancias de objetos eficientes que aprovechen los mismos métodos. Como ya se mencionó, no todos los objetos de matriz, que son instancias de la Formación() constructor, necesita su propio unirse() metodos Todas las instancias pueden aprovechar el mismo. unirse() Método porque el método se almacena en la cadena prototipo.

El prototipo es estándar en todos Función() Instancias

Todas las funciones son creadas desde un Función() constructor, incluso si no invoca directamente el Función() constructorvar add = new Function ('x', 'y', 'return x + z');) y en su lugar usa la notación literal (var add = function (x, y) return x + z;).

Cuando se crea una instancia de función, siempre se le da una prototipo Propiedad, que es un objeto vacío. En el siguiente ejemplo, definimos una función llamada myFunction y luego accedemos a la prototipo propiedad que es simplemente un objeto vacío.

Muestra: sample119.html

 

Asegúrese de comprender completamente que la propiedad prototipo proviene de Función() constructor. Es solo una vez que pretendemos utilizar nuestra función como una función constructora definida por el usuario que se aprovecha la propiedad prototipo, pero esto no cambia el hecho de que Función() El constructor le da a cada instancia una propiedad prototipo..


El valor por defecto prototipo La propiedad es una Objeto() Objeto

Todo esto prototipo hablar puede ser un poco pesado Verdaderamente, prototipo es solo una propiedad de objeto vacía llamada "prototipo" creada detrás de escena por JavaScript y puesta a disposición invocando el Función() constructor. Si lo hicieras manualmente, se vería algo como esto:

Muestra: sample120.html

 

De hecho, este código de ejemplo funciona realmente bien, esencialmente simplemente duplicando lo que JavaScript ya hace.

El valor de una propiedad prototipo se puede establecer en cualquiera de los valores complejos (objetos) disponibles en JavaScript. JavaScript ignorará cualquier propiedad prototipo establecida en un valor primitivo.


Las instancias creadas a partir de una función de constructor están vinculadas a las del constructor prototipo Propiedad

Si bien es solo un objeto, prototipo es especial porque la cadena de prototipos vincula cada instancia a la propiedad prototipo de su función constructora. Esto significa que cada vez que se crea un objeto a partir de una función de constructor utilizando el nuevo palabra clave (o cuando se crea una envoltura de objeto para un valor primitivo), agrega un enlace oculto entre la instancia de objeto creada y la propiedad prototipo de la función constructora utilizada para crearla. Este enlace es conocido dentro de la instancia como __proto__ (aunque solo se expone / admite mediante código en Firefox 2+, Safari, Chrome y Android). JavaScript conecta esto en segundo plano cuando se invoca una función constructora, y es este enlace que permite que la cadena del prototipo sea, bueno, una cadena. En el siguiente ejemplo, agregamos una propiedad al nativo Formación() constructores prototipo, que luego podemos acceder desde una Formación() instancia utilizando el __proto__ propiedad establecida en esa instancia.

Muestra: sample121.html

 

Desde el acceso __proto__ no es parte del estándar oficial de ECMA, hay una manera más universal de rastrear el enlace desde un objeto hasta el objeto prototipo que hereda, y es mediante el uso de constructor propiedad. Esto se demuestra en la siguiente muestra..

Muestra: sample122.html

 

En este ejemplo, el foo La propiedad se encuentra dentro del objeto prototipo. Debe darse cuenta de que esto solo es posible debido a la asociación entre la instancia de Formación() y el Formación() objeto prototipo constructor (Array.prototype). Simplemente pon, myArray .__ proto__ (o myArray.constructor.prototype) referencias Array.prototype.


Última parada en el prototipo La cadena es Objeto.prototipo

Dado que la propiedad prototipo es un objeto, la última parada en la cadena o búsqueda del prototipo es en Objeto.prototipo. En el código que sigue, creo myArray, que es una matriz vacía. Entonces intento acceder a una propiedad de myArray que aún no se ha definido, comprometiendo la cadena de búsqueda prototipo. los myArray objeto es examinado para la propiedad foo. Al estar ausente, se busca el inmueble en. Array.prototype, Pero tampoco está ahí. Así que el lugar final se ve JavaScript es Objeto.prototipo. Debido a que no está definido en ninguno de esos tres objetos, la propiedad es indefinido.

Muestra: sample123.html

 

Tome nota de que la cadena se detuvo con Objeto.prototipo. El último lugar que buscamos fue foo. Objeto.prototipo.

¡Cuidadoso! Todo lo que se agregue a Object.prototype se mostrará en un bucle for in.


los prototipo La cadena devuelve la primera coincidencia de propiedades que encuentra en la cadena

Al igual que la cadena de alcance, el prototipo La cadena utilizará el primer valor que encuentre durante la búsqueda de la cadena..

Modificando el ejemplo del código anterior, si agregamos el mismo valor al Objeto.prototipo y Array.prototype objetos, y luego intentó acceder a un valor en una instancia de matriz, el valor devuelto sería de la Array.prototype objeto.

Muestra: sample124.html

 

En esta muestra, el valor foo en Array.prototype.foo es la sombra, o enmascaramiento, la foo valor encontrado en Object.prototype.foo. Solo recuerde que la búsqueda termina cuando la propiedad se encuentra en la cadena, incluso si el mismo nombre de propiedad también se usa más arriba en la cadena.


Sustitución del prototipo La propiedad con un objeto nuevo elimina la propiedad de constructor predeterminada

Es posible reemplazar el valor predeterminado de un prototipo Propiedad con un nuevo valor. Sin embargo, al hacerlo se eliminará la propiedad del constructor predeterminada que se encuentra en el "pre-hecho" prototipo objeto a menos que especifique manualmente uno.

En el siguiente código creamos un Foo función constructora, reemplazar el prototipo propiedad con un nuevo objeto vacío, y verifique que la propiedad del constructor esté rota (ahora hace referencia a los menos útiles Objeto prototipo).

Muestra: sample125.html

 

Si pretende reemplazar el predeterminado prototipo propiedad (común con algunos patrones JS OOP) configurada por JavaScript, debe volver a conectar una propiedad de constructor que haga referencia a la función de constructor. En el siguiente ejemplo, modificamos nuestro código anterior para que el constructor la propiedad nuevamente proporcionará una referencia a la función constructora apropiada.

Muestra: sample126.html

 

Instancias que heredan propiedades de prototipo Siempre obtendrá los últimos valores

La propiedad del prototipo es dinámica en el sentido de que las instancias siempre obtendrán el último valor del prototipo, independientemente de cuándo se crearon instancias, cambios o anexos. En el siguiente código creamos un Foo constructor, añada la propiedad X al prototipo, y luego crear una instancia de Foo () llamado FooInstance. A continuación, registramos el valor de X. Luego, actualizamos el valor de prototipos de x y lo registramos nuevamente para encontrar que nuestra instancia tiene acceso al último valor encontrado en prototipo objeto.

Muestra: sample127.html

 

Dado el funcionamiento de la cadena de búsqueda, este comportamiento no debería ser tan sorprendente. Si se está preguntando, esto funciona de la misma manera, independientemente de si utiliza el valor predeterminado. prototipo objetar o anularlo con el tuyo. En la siguiente muestra, sustituyo el predeterminado prototipo objetar para demostrar este hecho.

Muestra: sample128.html

 

Sustitución del prototipo La propiedad con un objeto nuevo no actualiza las instancias anteriores

Podría pensar que puede reemplazar el prototipo propiedad completamente en cualquier momento y que todas las instancias se actualizarán, pero esto no es correcto. Cuando creas una instancia, esa instancia estará vinculada a la prototipo que fue acuñado en el momento de la instanciación. Proporcionar un nuevo objeto como la propiedad prototipo no actualiza la conexión entre las instancias ya creadas y la nueva prototipo.

Pero recuerde, como dije anteriormente, puede actualizar o agregar a los creados originalmente prototipo objeto y esos valores permanecen conectados a la primera instancia (s).

Muestra: sample129.html

 

La idea clave para llevar aquí es que un prototipo de objetos no debe reemplazarse con un objeto nuevo una vez que comience a crear instancias. De lo contrario, se crearán instancias que tengan un enlace a diferentes prototipos..

Los constructores definidos por el usuario pueden aprovechar lo mismo prototipo Herencia como constructores nativos

Con suerte, en este punto del artículo, se está hundiendo en cómo el propio JavaScript aprovecha la prototipo propiedad por herencia (Array.prototype). Este mismo patrón se puede aprovechar al crear funciones de constructor definidas por el usuario no nativas. En la siguiente muestra, tomamos el clásico. Persona Objetar e imitar el patrón que usa JavaScript para la herencia..

Muestra: sample130.html

 

En este código, un Persona() Se crea la función constructora. Luego agregamos propiedades a la prototipo propiedad de Persona(), El cual puede ser heredado por todas las instancias. Claramente, puede aprovechar la cadena de prototipos en su código de la misma manera que JavaScript lo aprovecha para la herencia de objetos nativos.

Como un buen ejemplo de cómo podría aprovechar esto, puede crear una función constructora cuyas instancias heredan la piernas y brazos Propiedades si no se proporcionan como parámetros. En la siguiente muestra, si el Persona() se le envían parámetros al constructor, los parámetros se usan como propiedades de instancia, pero si uno o más parámetros no se proporcionan, hay un respaldo. Estas propiedades de instancia luego sombrean o enmascaran las propiedades heredadas, dándole lo mejor de ambos mundos.

Muestra: sample131.html

 

Creando Cadenas de Herencias (la Intención Original)

La herencia prototípica fue concebida para permitir cadenas de herencia que imitan los patrones de herencia encontrados en los lenguajes de programación orientados a objetos tradicionales. Para que un objeto se herede de otro objeto en JavaScript, todo lo que tiene que hacer es crear una instancia del objeto del que desea heredar y asignarlo a la prototipo Propiedad del objeto que está haciendo el heredero..

En el ejemplo de código que sigue, Cocinero objetos (cody) heredar de Persona(). Esto significa que si una propiedad no se encuentra en un Cocinero objeto, se buscará en el prototipo de la función que creó Persona() objetos. Para conectar la herencia, todo lo que tiene que hacer es crear una instancia de Persona() como el valor para Chef.prototipo (Chef.prototype = nueva Persona (); ).

Muestra: sample132.html

 

Conclusión

Todo lo que hicimos en esta muestra fue aprovechar un sistema que ya estaba en su lugar con los objetos nativos. Considere eso Persona() no es diferente al predeterminado Objeto() Valor para las propiedades del prototipo. En otras palabras, esto es exactamente lo que sucede cuando una propiedad prototipo, que contiene su valor predeterminado vacío Objeto() valor, mira al prototipo de la función constructora creada (Objeto.prototipo) para propiedades heredadas.