Maybaygiare.org

Blog Network

Atributos de propiedades de objetos en JavaScript

En esta publicación de blog, echamos un vistazo más de cerca a cómo la especificación ECMAScript ve los objetos JavaScript. En particular, las propiedades no son atómicas en la especificación, sino compuestas de múltiples atributos (campos de pensamiento en un registro). Incluso el valor de una propiedad de datos se almacena en un atributo!

Tabla de contenido:

La estructura de objetos #

En la especificación ECMAScript, un objeto consta de:

  • Ranuras internas, que son ubicaciones de almacenamiento a las que no se puede acceder desde JavaScript, solo para las operaciones de la especificación.
  • Una colección de propiedades. Cada propiedad asocia una clave con atributos (campos de pensamiento en un registro).

Ranuras internas #

Así es como la especificación describe las ranuras internas (el énfasis es mío):

  • Las ranuras internas corresponden al estado interno que está asociado con los objetos y utilizado por varios algoritmos de especificación ECMAScript.
  • Las ranuras internas no son propiedades de objetos y no se heredan.
  • Dependiendo de la especificación de ranura interna específica, dicho estado puede consistir en valores:
    • de cualquier tipo de lenguaje ECMAScript o
    • de valores de tipo de especificación ECMAScript específicos.
  • A menos que se especifique explícitamente lo contrario, las ranuras internas se asignan como parte del proceso de creación de un objeto y es posible que no se agreguen dinámicamente a un objeto.
  • A menos que se especifique lo contrario, el valor inicial de una ranura interna es el valor undefined.
  • Varios algoritmos dentro de esta especificación crean objetos que tienen ranuras internas. Sin embargo, el lenguaje ECMAScript no proporciona una forma directa de asociar ranuras internas con un objeto.
  • Los métodos internos y las ranuras internas se identifican dentro de esta especificación utilizando nombres encerrados entre corchetes dobles ].

Hay dos tipos de ranuras internas:

  • Ranuras de método para manipular objetos (obtener propiedades, establecer propiedades, etc.).)
  • Data slots with storage (listed in the table below)
Internal data slot Type
] null | object
] boolean
] List of entries

Descriptions for these data ranuras:

llaves del inmueble #

La clave de una propiedad es:

  • cadena
  • Un símbolo

los atributos de Propiedad #

Hay dos tipos de propiedades y tienen diferentes atributos:

  • Una propiedad de datos almacenes de datos. Sus atributos value contiene cualquier valor de JavaScript.
  • Una propiedad accessor tiene una función getter y / o una función setter. El primero se almacena en el atributo get, el último en el atributo set.

La siguiente tabla enumera todos los atributos de propiedad.

Kind of property Name and type of attribute Default value
Data property value: any undefined
writable: boolean false
Accessor property get(): any undefined
set(v: any): void undefined
All properties configurable: boolean false
enumerable: boolean false

We have already encountered the attributes valueget, and set. The other attributes work as follows:

  • writable determina si se puede cambiar el valor de una propiedad de datos.
  • configurable determina si se pueden cambiar los atributos de una propiedad. Si es false, entonces:
    • No puede eliminar la propiedad.
    • No se puede cambiar una propiedad de una propiedad de datos a una propiedad de accessor o viceversa.
    • No puede cambiar ningún atributo que no sea value.
    • Sin embargo, se permite un cambio de atributo más: Usted puede cambiar writable de true a false. La lógica detrás de esta anomalía es histórica: La propiedad .length de los Arrays siempre ha sido escribible y no configurable. Permitir que se cambie su atributo writable nos permite congelar matrices.
  • enumerable influencias de algunas operaciones (como Object.assign()). Si es false, entonces esas operaciones ignoran la propiedad.

Descriptores de propiedad #

Un descriptor de propiedad codifica los atributos de una propiedad como un objeto JavaScript. Sus interfaces TypeScript se ven de la siguiente manera.

Los signos de interrogación indican que cada propiedad es opcional. Si omite una propiedad al pasar un descriptor a una operación, se utiliza su valor predeterminado.

Recuperando descriptores para propiedades #

El siguiente código recupera el descriptor de objeto para la propiedad de datos first:

En el siguiente ejemplo, recuperamos el descriptor de propiedad para el getter fullName:

Usando desc()en la línea A es una solución alternativa para que .deepEqual() funcione.

Crear nuevas propiedades a través de descriptores #

También puede crear nuevas propiedades a través de descriptores de propiedades:

Cambiar las propiedades existentes a través de descriptores #

Si ya existe una propiedad propia, definirla a través de un descriptor cambia esa propiedad. Por un lado, que nos permite usar Object.defineProperty() como asignación:

Por otro lado, también podemos usar Object.defineProperty() para convertir una propiedad de datos en un getter (y viceversa):

Trampa: las propiedades de solo lectura heredadas no se pueden asignar a #

Si una propiedad heredada es de solo lectura, no podemos usar asignación para cambiarla. La razón es que la anulación de una propiedad heredada mediante la creación de una propiedad propia puede verse como un cambio no destructivo de la propiedad heredada. Podría decirse que si una propiedad no es escribible, no deberíamos ser capaces de hacerlo.

veamos un ejemplo:

No podemos cambiar la propiedad mediante asignación. Pero aún podemos crear una propiedad propia definiéndola:

Object.defineProperty(obj, 'prop', {value: 2});assert.equal(obj.prop, 2);

Las propiedades de acceso que no tienen un configurador también se consideran de solo lectura:

API: descriptores de propiedad #

Las siguientes funciones le permiten trabajar con descriptores de propiedad:

Casos de uso para Object.Objeto getOwnPropertyDescriptors () #

.getOwnPropertyDescriptors (): copiar propiedades en un objeto #

Desde ES6, JavaScript ya ha tenido un método de herramienta para copiar propiedades: Object.assign(). Sin embargo, este método utiliza operaciones simples de get y set para copiar una propiedad cuya clave es key:

target = source;

Eso significa que solo crea una copia fiel de una propiedad si:

  • Su atributo writable es true y su atributo enumerable es true (porque así es como la asignación crea propiedades).
  • es una propiedad de datos.

El siguiente ejemplo ilustra esta limitación. Objeto source tiene un setter cuya clave es data.

Si usamos Object.assign() para copiar la propiedad data, entonces la propiedad accessor data se convierte en una propiedad de datos:

Afortunadamente, utilizando Object.getOwnPropertyDescriptors() junto con Object.defineProperties() copia fielmente la propiedad data:

Trampa: métodos de copia que usan super #

Un método que usa super está firmemente conectado con su objeto home (el objeto en el que está almacenado). Actualmente no hay forma de copiar o mover un método de este tipo a un objeto diferente.Objeto

.getOwnPropertyDescriptors (): clonación de objetos #

La clonación superficial es similar a las propiedades de copia, por lo que Object.getOwnPropertyDescriptors() también es una buena opción aquí.

Para crear el clon, usamos Object.create():

Deja una respuesta

Tu dirección de correo electrónico no será publicada.