Trabajar con objetos y propiedades

Un objeto complejo puede contener cualquier valor de JavaScript permitido. En el siguiente código, creo un Objeto() objeto llamado miObjeto y luego agregue propiedades que representan la mayoría de los valores disponibles en JavaScript.


Objetos complejos

Muestra: sample29.html

 

El concepto simple que se aprende aquí es que los objetos complejos pueden contener o referirse a cualquier cosa que pueda expresar nominalmente en JavaScript. No debe sorprenderse cuando vea que se hace esto, ya que todos los objetos nativos pueden mutarse. Esto incluso se aplica a Cuerda(), Número(), y Booleano () valores en su forma de objeto, es decir, cuando se crean con el nuevo operador.


Encapsular objetos complejos de una manera programáticamente beneficiosa

los Objeto(), Formación(), y Función() Los objetos pueden contener otros objetos complejos. En el siguiente ejemplo, demuestro esto configurando un árbol de objetos usando Objeto() objetos.

Muestra: sample30.html

 

Lo mismo se puede hacer con un Formación() objeto (también conocido como matriz multidimensional), o con una Función() objeto.

Muestra: sample31.html

 

El concepto principal que se debe quitar aquí es que algunos de los objetos complejos están diseñados para encapsular otros objetos de una manera programáticamente beneficiosa..


Obtención, configuración y actualización de las propiedades de un objeto mediante la notación de puntos o la notación de corchetes

Podemos obtener, configurar o actualizar las propiedades de un objeto usando la notación de puntos o la notación de corchetes.

En la siguiente muestra, demuestro la notación de puntos, que se logra utilizando el nombre del objeto seguido de un punto, y luego seguido por la propiedad para obtener, configurar o actualizar (por ejemplo,., objectName.property).

Muestra: sample32.html

 

La notación de puntos es la notación más común para obtener, configurar o actualizar las propiedades de un objeto..

La notación de corchetes, a menos que se requiera, no es tan comúnmente utilizada. En la siguiente muestra, sustituyo la notación de puntos utilizada en la muestra anterior por la notación de corchete. El nombre del objeto va seguido de un corchete de apertura, el nombre de la propiedad (entre comillas) y luego un corchete de cierre:

Muestra: sample33.html

 

La notación de corchetes puede ser muy útil cuando necesita acceder a una clave de propiedad y con lo que tiene que trabajar es una variable que contiene un valor de cadena que representa el nombre de la propiedad. En la siguiente muestra, demuestro la ventaja de la notación de corchetes sobre la notación de puntos al usarla para acceder a la propiedad foobar. Hago esto usando dos variables que, cuando se unen, producen la versión de cadena de la clave de propiedad contenida en foobarObject.

Muestra: sample34.html

 

Además, la notación de corchetes puede ser útil para obtener nombres de propiedades que son identificadores de JavaScript no válidos. En el siguiente código, uso un número y una palabra clave reservada como un nombre de propiedad (válido como una cadena) al que solo puede acceder la notación de corchetes.

Muestra: sample35.html

 

Porque los objetos pueden contener otros objetos., cody.object.object.object.object o cody ['objeto'] ['objeto'] ['objeto'] ['objeto'] Se puede ver a veces. Esto se llama encadenamiento de objetos. La encapsulación de objetos puede continuar indefinidamente..

Los objetos son mutables en JavaScript, lo que significa que obtenerlos, configurarlos o actualizarlos se pueden realizar en la mayoría de los objetos en cualquier momento. Usando la notación de corchete (por ejemplo,., cody ['edad']), puedes imitar matrices asociativas encontradas en otros idiomas.

Si una propiedad dentro de un objeto es un método, todo lo que tiene que hacer es usar el () operadores (por ejemplo,., cody.getGender ()) para invocar el método de propiedad.


Eliminar propiedades de objeto

los borrar El operador puede usarse para eliminar completamente las propiedades de un objeto. En el siguiente fragmento de código, eliminamos el bar propiedad de la foo objeto.

Muestra: sample36.html

 

borrar no eliminará las propiedades que se encuentran en la cadena de prototipos.

Eliminar es la única forma de eliminar realmente una propiedad de un objeto. Establecer una propiedad para indefinido o nulo Solo cambia el valor de la propiedad. No elimina la propiedad del objeto..


Cómo se resuelven las referencias a las propiedades de los objetos

Si intenta acceder a una propiedad que no está contenida en un objeto, JavaScript intentará encontrar la propiedad o el método utilizando la cadena de prototipo. En el siguiente ejemplo, creo una matriz e intento acceder a una propiedad llamada foo Eso aún no se ha definido. Podrías pensar eso porque myArray.foo no es una propiedad de la myArray objeto, JavaScript volverá inmediatamente indefinido. Pero JavaScript buscará en dos lugares más (Array.prototype y entonces Objeto.prototipo) por el valor de foo antes de que vuelva indefinido.

Muestra: sample37.html

 

la propiedad. Si tiene la propiedad, devolverá el valor de la propiedad y no se producirá ninguna herencia porque la cadena del prototipo no está apalancada. Si la instancia no tiene la propiedad, JavaScript la buscará en la función constructora del objeto prototipo objeto.

Todas las instancias de objetos tienen una propiedad que es un enlace secreto (también conocido como __proto__) a la función constructora que creó la instancia. Este enlace secreto se puede aprovechar para capturar la función de constructor, específicamente la propiedad prototipo de la función de constructor de instancias.

Este es uno de los aspectos más confusos de los objetos en JavaScript. Pero razonemos esto. Recuerda que una función es también un objeto con propiedades. Tiene sentido permitir que los objetos hereden propiedades de otros objetos. Al igual que decir: "Oye, objeto B, me gustaría que compartieras todas las propiedades que tiene el objeto A". JavaScript transfiere todo esto para objetos nativos por defecto a través de prototipo objeto. Cuando crea sus propias funciones de constructor, también puede aprovechar el encadenamiento de prototipos.

Cómo exactamente JavaScript logra esto es confuso hasta que lo ve por lo que es: solo un conjunto de reglas. Vamos a crear una matriz para examinar la prototipo propiedad más cerca.

Muestra: sample38.html

 

Nuestro Formación() La instancia es un objeto con propiedades y métodos. A medida que accedemos a uno de los métodos de matriz, como unirse(), preguntémonos: ¿La instancia myArray creada a partir de Formación() constructor tiene su propio unirse() ¿método? Vamos a revisar.

Muestra: sample39.html

 

No, no lo hace. Sin embargo, myArray tiene acceso a la unirse() Método como si fuera propiedad propia. ¿Lo que pasó aquí? Bueno, acabas de observar la cadena del prototipo en acción. Accedimos a una propiedad que, aunque no está contenida en el objeto myArray, se puede encontrar mediante JavaScript en otro lugar. Que en otro lugar es muy específico. Cuando el Formación() constructor fue creado por JavaScript, el unirse() Método fue agregado (entre otros) como propiedad de la prototipo propiedad de Formación().

Para reiterar, si intenta acceder a una propiedad en un objeto que no la contiene, JavaScript buscará prototipo Cadena para este valor. Primero mirará la función constructora que creó el objeto (por ejemplo,., Formación), e inspeccionar su prototipo (por ejemplo,., Array.prototype) para ver si la propiedad se puede encontrar allí. Si el primer objeto prototipo no tiene la propiedad, entonces JavaScript sigue buscando la cadena en el constructor detrás del constructor inicial. Puede hacer esto hasta el final de la cadena..

¿Dónde termina la cadena? Examinemos el ejemplo de nuevo, invocando el toLocaleString () método en myArray.

Muestra: sample40.html

 

los toLocaleString () método no está definido dentro de la myArray objeto. Por lo tanto, se invoca la regla de encadenamiento de prototipos y JavaScript busca la propiedad en el Formación constructores de propiedad prototipo (por ejemplo,., Array.prototype). Tampoco está allí, por lo que la regla de la cadena se invoca de nuevo y buscamos la propiedad en el Objeto() propiedad prototipo (Objeto.prototipo). Y sí, allí se encuentra. Si no se hubiera encontrado allí, JavaScript habría producido un error que indicaba que la propiedad estaba indefinido.

Dado que todas las propiedades de prototipo son objetos, el enlace final en la cadena es Objeto.prototipo. No hay otra propiedad de prototipo de constructor que pueda ser examinada..

Hay un capítulo completo por delante que divide la cadena del prototipo en partes más pequeñas, por lo que si se perdió por completo, lea ese capítulo y luego vuelva a esta explicación para consolidar su comprensión. A partir de esta breve lectura al respecto, espero que entienda que cuando no se encuentra una propiedad (y se considera indefinido), JavaScript habrá examinado varios objetos prototipo para determinar que una propiedad es indefinido. Siempre se produce una búsqueda, y este proceso de búsqueda es la forma en que JavaScript maneja la herencia, así como las búsquedas de propiedades simples.


Utilizando hasOwnProperty verificar que una propiedad de objeto no es de la cadena de prototipo

Mientras que la en El operador puede verificar las propiedades de un objeto, incluidas las propiedades de la cadena del prototipo, el hasOwnProperty El método puede verificar un objeto para una propiedad que no pertenece a la cadena del prototipo.

En la siguiente muestra, queremos saber si miObjeto contiene la propiedad foo, y que no está heredando la propiedad de la cadena prototipo. Para ello, preguntamos si miObjeto tiene su propia propiedad llamada foo.

Muestra: sample41.html

 

los hasOwnProperty El método debe aprovecharse cuando se necesita determinar si una propiedad es local a un objeto o se hereda de la cadena de prototipo..


Comprobando si un objeto contiene una propiedad dada usando el en Operador

los en el operador se usa para verificar (verdadero o falso) si un objeto contiene una propiedad dada. En esta muestra, estamos comprobando si foo es una propiedad en miObjeto.

Muestra: sample42.html

 

Debe tener en cuenta que la en El operador no solo comprueba las propiedades contenidas en el objeto al que se hace referencia, sino también las propiedades que el objeto hereda a través de prototipo cadena. Por lo tanto, se aplican las mismas reglas de búsqueda de propiedades y la propiedad, si no está en el objeto actual, se buscará en la prototipo cadena.

Esto significa que myObject en la muestra anterior realmente contiene un Encadenar método de propiedad a través de la prototipo cadenaObject.prototype.toString), incluso si no especificamos uno (por ejemplo,., myObject.toString = 'foo').

Muestra: sample43.html

 

En el último ejemplo de código, la propiedad toString no está literalmente dentro del objeto myObject. Sin embargo, se hereda de Objeto.prototipo, y así el en el operador concluye que miObjeto de hecho, tiene un heredado Encadenar() método de propiedad.


Enumerar (recorrer en bucle) las propiedades de un objeto usando el para en Lazo

Mediante el uso para en, Podemos hacer un bucle sobre cada propiedad en un objeto. En la siguiente muestra, estamos usando el para en bucle para recuperar los nombres de propiedad del objeto cody.

Muestra: sample44.html

 

los para en bucle tiene un inconveniente. No solo accederá a las propiedades del objeto específico sobre el que se realiza el bucle. También incluirá en el bucle cualquier propiedad heredada (a través de la cadena del prototipo) por el objeto. Por lo tanto, si este no es el resultado deseado, y la mayoría de las veces no lo es, tenemos que usar un simple Si declaración dentro del bucle para asegurarnos de que solo accedemos a las propiedades contenidas dentro del objeto específico sobre el que estamos realizando el bucle. Esto se puede hacer usando el hasOwnProperty () Método heredado por todos los objetos..

El orden en el que se accede a las propiedades en el bucle no es siempre el orden en el que se definen dentro del bucle. Además, el orden en el que definió las propiedades no es necesariamente el orden al que se accede.

Solo las propiedades que son enumerables (es decir, disponibles cuando se realiza un bucle sobre las propiedades de un objeto) se muestran con la para en lazo. Por ejemplo, la propiedad del constructor no se mostrará. Es posible verificar qué propiedades son enumerables con el propertyIsEnumerable () método.


Objetos de host y objetos nativos

Debe tener en cuenta que el entorno (por ejemplo, un navegador web) en el que se ejecuta JavaScript normalmente contiene lo que se conoce como objetos host. Los objetos del host no forman parte de la implementación de ECMAScript, pero están disponibles como objetos durante la ejecución. Por supuesto, la disponibilidad y el comportamiento de un objeto host dependen completamente de lo que proporciona el entorno host..

Por ejemplo, en el entorno del navegador web, el objeto ventana / cabeza y todos sus objetos que contienen (excluyendo lo que proporciona JavaScript) se consideran objetos host..

En el siguiente ejemplo, examino las propiedades del ventana objeto.

Muestra: sample45.html

 

Es posible que haya notado que los objetos de JavaScript nativos no están listados entre los objetos del host. Es bastante común que un navegador distinga entre objetos host y objetos nativos.

En lo que respecta a los navegadores web, el más famoso de todos los objetos alojados es la interfaz para trabajar con documentos HTML, también conocido como DOM. El siguiente ejemplo es un método para enumerar todos los objetos contenidos dentro del window.document Objeto proporcionado por el entorno del navegador..

Muestra: sample46.html

 

Lo que quiero que aprendas aquí es que la especificación de JavaScript no se relaciona con los objetos del host y viceversa. Existe una línea divisoria entre lo que proporciona JavaScript (por ejemplo, JavaScript 1.5, ECMA-262, Edición 3 versus JavaScript 1.6 de Mozilla, 1.7, 1.8, 1.8.1, 1.8.5) y lo que proporciona el entorno de host, y estos dos no deberían estar confundido.

El entorno host (por ejemplo, un navegador web) que ejecuta código JavaScript generalmente proporciona el objeto principal (por ejemplo, un objeto de ventana en un navegador web) donde se almacenan las partes nativas del idioma junto con los objetos host (por ejemplo,., ubicación de ventana en un navegador web) y objetos definidos por el usuario (por ejemplo, el código que escribe para ejecutarse en el navegador web).

A veces, un fabricante de navegadores web, como anfitrión del intérprete de JavaScript, impulsará una versión de JavaScript o agregará especificaciones futuras a JavaScript antes de que hayan sido aprobadas (por ejemplo, Firefox JavaScript 1.6, 1.7, 1.8, 1.8.1, 1.8 de Mozilla). 5).


Mejora y extensión de objetos con Underscore.js

Falta JavaScript 1.5 cuando llega el momento de manipular y administrar seriamente los objetos. Si está ejecutando JavaScript en un navegador web, me gustaría estar en negrita aquí y sugerir el uso de Underscore.js cuando necesite más funcionalidad de la que proporciona JavaScript 1.5. Underscore.js proporciona la siguiente funcionalidad cuando se trata de objetos.

Estas funciones funcionan en todos los objetos y matrices:

  • cada()
  • mapa()
  • reducir()
  • reduceRight ()
  • detectar()
  • seleccionar()
  • rechazar()
  • todos()
  • alguna()
  • incluir()
  • invocar()
  • arrancar()
  • max ()
  • min ()
  • ordenar por()
  • sortIndex ()
  • toArray ()
  • tamaño()

Estas funciones funcionan en todos los objetos:

  • llaves()
  • valores()
  • funciones ()
  • ampliar()
  • clon()
  • grifo()
  • es igual()
  • esta vacio()
  • isElement ()
  • isArray ()
  • isArgumentos
  • isFunction ()
  • isString ()
  • es número
  • isBoolean
  • isDate
  • isRegExp
  • isNaN
  • es nulo
  • es indefinido

Conclusión

Me gusta esta biblioteca porque aprovecha las nuevas adiciones nativas a JavaScript donde los navegadores las admiten, pero también proporciona la misma funcionalidad a los navegadores que no lo hacen, todo sin cambiar la implementación nativa de JavaScript a menos que tenga que hacerlo..

Antes de comenzar a usar Underscore.js, asegúrese de que la funcionalidad que necesita no esté ya provista por una biblioteca de JavaScript o un marco que ya esté en uso en su código..