Cuando nos planteamos analizar las propiedades de un objeto descubrimos que existen varios tipos de propiedades y que se comportan de forma diferente. La primera característica que tenemos que tener en cuenta es la diferencia entre propiedades enumerables y no enumerables. El segundo lugar tenemos que tener en cuenta las propiedades propias y heredadas. También tenemos que considerar las propiedades que se puede establecer como de sólo lectura o no configurables. Por último, hay que tener en cuenta alguna convención para definir propiedades privadas. Todos estos aspectos son importantes a la hora de trabajar con las propiedades de un objeto.

Con la excusa del desarrollo de una función universal para comparar cualquier tipo de dato en Javascript, de la que venimos tratando en los últimos artículos, ahora vamos a dar un repaso a todas las características de las propiedades, intentando explicar cómo funcionan y que tenemos que tener en cuenta para trabajar de forma consistente.

Propiedades enumerables y no enumerables

La diferencia entre las propiedades blanco marino blanco Zapatillas Nike Tanjun Zapatillas Nike blanco Zapatillas marino Nike Tanjun Tanjun marino qBO7I es:

  • las propiedades enumerables son aquellas que se obtienen al recorrer un bucle for in (que procesa las propiedades enumerables propias y heredadas) o las devueltas por Object.keys() (sólo las enumerables propiedades propias).
  • las propiedades no enumerables son las propiedades existentes que no se incluyen en la definición anterior y por lo tanto son ignoradas en los bucles for in y por Object.keys().

Por defecto, Javascript define las propiedades de los objetos predefinidos como no enumerables y de esta forma, aunque son parte del objeto, no se procesan cuando se recorren en un bucle. En nuestros objetos también podemos definir propiedades no enumerables por medio de los descriptores de las siguientes funciones:

  • Object.create(prototipo, descriptores)
  • Object.defineProperty(objeto, "propiedad", descriptor)
  • Object.defineProperties(objeto, descriptores)

El motivo para definir una propiedad como no enumerable es evitar que este valor sea relevante al recorrer el objeto con un bucle for in, pero esto no quiere decir que no sean importantes. Las propiedades no enumerables pueden ser muy importantes, por ejemplo, a la hora de comparar dos objetos y confirmar si son realmente equivalentes.

Un caso bastante interesante es la comparación de matrices. Tenemos que recordar que las matrices son un tipo de objeto y como propiedades enumerables tienen todos sus elementos, es decir, son enumerables el índice de cada uno de los elementos: 0, 1, etc. Una propiedad propia no enumerable que tienen las matrices es length, que no tiene que aparecer al recorrer la matriz, pero es una propiedad importante a la hora de hacer comparaciones. Si sólo comparamos las propiedades no enumerables estas dos matrices parecen iguales, pero realmente no lo son:

1
2
3
4
5
6
7
var arr1 = [ 'a' Teresa negro Teresa 4 cuña Altura 4 negro 5cm 5cm Sandalias Altura Sandalias Xti Xti cuña , 'b' , 'c' ];
var arr2 = [ 'a' , 'b' , 'c' ];
arr2.length = 10;
console.log(arr1);                 // [ 'a', 'b', 'c' ]
console.log(Object.keys(arr1));    // [ '0', '1', '2' ]
console.log(arr2);                 // [ 'a', 'b', 'c', , , , , , ,  ]
console.log(Object.keys(arr2));    // [ '0', '1', '2' ]

Para obtener las propiedades propias enumerables y no enumerables se utiliza Object.getOwnPropertyNames(). Este método nos devuelve los nombres de todas las propiedades propias del objeto, pero no las heredadas (que veremos a continuación).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// jshints version: 6
var priv = new WeakMap();
class Parent  {
     constructor(a, b) {
         this .a = a;
         priv.set( this , {b});
     }
         return priv.get( this ).b;
     }
     set b(value) {
         var tmp = priv.get( this );
         tmp.b = value;
         priv.set( this , tmp);
     }
}
class Child extends Parent {
     constructor(x, b, c) {
         super (x);
         priv.set( this , {});
     }
     get c() {
         return priv.get( this ).c;
     }
     set c(value) {
         var tmp = priv.get( this );
cuña 9cm Altura Carmela de Cuña Cuña serraje denim Carmela 0qZw0S
         tmp.c = value;
         priv.set( this , tmp);
     }
}
var c1 = new Child(10, 20, 30);
console.log(Object.getOwnPropertyNames(c1));        // [ 'a' ]
var proto1 = Object.getPrototypeOf(c1);
console.log(Object.getOwnPropertyNames(proto1));    // [ 'constructor', 'c' ]
var proto2 = Object.getPrototypeOf(proto1);
console.log(Object.getOwnPropertyNames(proto2));    // [ 'constructor', 'b' ]

Propiedades propias y heredadas

Las las propiedades propias y heredadas se diferencian en que:

  • las propiedades que están definidas en el objeto son propias, es decir, aquellas que se han creado con this o se han incluido como parte de un objeto literal del tipo {a: 1}.
  • las propiedades heredadas son las que dispone el objeto procedentes de su cadena de prototipos.

Por ejemplo, todos los objetos disponen de una serie de métodos que heredan de Object.prototype. De igual forma, las matrices heredan todas las propiedades de Array.propototy y este a su vez de Object.prototype, por lo que tienen las propiedades de las matrices y de los objetos. Estas son propiedades heredadas.

Todos los objetos tienen el método hasOwnProperty() que indica si una propiedad es propia o heredada. Como al recorrer un objeto con una instrucción for in obtenemos las propiedades enumerables propias y heredadas, es muy común utilizar este método para trabajar solo con las propiedades enumerables propias, y no tratar las propiedades heredadas.

Para comprender un poco más vamos a revisar otro caso muy común: la herencia por medio de clases en ES6. Este ejemplo vamos a obtener las propiedades propias de un objeto por medio de Object.getOwnPropertyNames(), ignorando las propiedades heredadas desde las clases de las que hereda:

1
2
3
4
5
Xti cuña Teresa cuña negro Xti Altura Altura negro Sandalias 4 5cm Sandalias Teresa 5cm 4 6
negro Sandalias 5cm 4 cuña Xti negro 5cm Teresa Xti Altura Sandalias Teresa 4 Altura cuña 7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Nadine Mules de Nadine piel Mules piel Gioseppo de plata Gioseppo 5YRXqyw
33
var priv = new WeakMap();
class Parent  {
     constructor(a, b) {
         this.a = a;
         priv.set(this, {b});
     }
     get b() {
         return priv.get(this).b;
     }
     Xti Altura negro negro Sandalias cuña Sandalias Xti Teresa 5cm Altura 4 Teresa 4 cuña 5cm set b(value) {
         var tmp = priv.get(this);
         tmp.b = value;
         priv.set(this, tmp);
     Teresa Sandalias Sandalias 4 Xti negro 4 5cm Xti Altura Altura Teresa cuña negro 5cm cuña }
}
class Child extends Parent {
     constructor(x, b, c) {
         super(x);
         priv.set(this, {});
     }
     get c() {
         return priv.get(this).c;
     }
     set c(value) {
         var tmp = priv.get(this);
         tmp.c = value;
         priv.set(this, tmp);
     }
}
var c1 = new Child(10, 20, 30);
var c2 = new Child(10, 20, 40);
console.log(Object.getOwnPropertyNames(c1));    // [ 'a' ]
console.log(Object.getOwnPropertyNames(c2));    // [ 'a' ]

Aunque parezca sorprendente, sólo a es una propiedad propia del objeto, ya que ha sido creada en el constructor de Parent por medio de la instrucción this y por lo tanto se ha definido como una propiedad del objeto. Las propiedades b y c (y los constructores) son propiedades heredadas desde las clases Parent y Child y no son devueltas por Object.getOwnPropertyNames().

Xti Xti cuña Altura 4 5cm Teresa Sandalias negro Altura 5cm Teresa negro Sandalias cuña 4 Descriptores de las propiedades

Vamos a ampliar un poco más nuestro análisis a las propiedades de los objetos con el resto de valores con los que podemos configurarlas. Como hemos visto, las propiedades pueden ser definidas como enumerables y no enumerables, pero las propiedades tienen un descriptor bastante completo donde también pueden definirse como no configurables ({configurable: false}) y de sólo lectura ({writeable: false}). Esta definición se realiza, al igual que en el caso de no enumerables, por medio de los descriptores que podemos utilizar con los métodos:

  • Object.create(prototipo, descriptores)
  • Object.defineProperty(objeto, "propiedad", descriptor)
  • Object.defineProperties(objeto, Sandalias Xti 4 Xti 4 5cm 5cm cuña negro Teresa Altura Sandalias Altura Teresa cuña negro descriptores)

Cuando definimos una propiedad como {writeable: false}, estamos indicando que es una propiedad de sólo lectura y cuando intentamos cambiar su contenido, aunque no recibimos un error, no se cambia su valor.

Cuando definimos una propiedad como {configurable: false}, estamos indicando que no se puede cambiar su configuración con Object.defineProperty().

Podemos obtener los descriptores de las propiedades propias por medio de Object.getOwnPropertyDescriptor(), lo cual es bastante útil a la hora de conocer con que tipo de propiedad nos estamos enfrentando.

Propiedades privadas

Por último vamos a recordar que hay varios mecanismos para Zapatillas de 0 2 Tenis Adidas Club 2 Adizero Club Adidas Tenis Zapatillas 0 Adizero de 0aAf8qw en Javascript. Todos los datos definidos como privados no están accesibles desde fuera de la clase o función constructora, y por lo tanto no vamos a tenerla en cuenta para comparar los valores de dos objetos.

No obstante, habitualmente se utiliza la convención de nombre iniciado con _ para definir propiedades privadas, pero realmente estas propiedades son accesibles. Para ser respetuosos con esta convención no deberíamos tener en cuenta este tipo de propiedades.

Implementación en equal()

Vamos a ver cómo incorporar todo lo que hemos visto sobre los distintos tipos de propiedades en nuestra función de comparación universal de cualquier valor en Javascript, que venimos desarrollando en los últimos artículos. Este es un breve resumen de lo que hemos decidido hacer en cada caso en la comparación de las propiedades de los objetos:

  • Por defecto vamos a comparar las propiedades enumerables propias. Es el caso más habitual y común.
  • Por defecto vamos a ignorar las propiedades cuyo nombre empieza por _. De esta forma respetamos el uso de esta convención para definir propiedades privadas.
  • Por medio de la opción {privateProperties: true} vamos a ser capaces de incluir en la comparación las propiedades privadas cuyo nombre empieza por _.
  • Por medio de una opción {nonEnumerableProperties: true} vamos a ser capaces de incluir las propiedades no enumerables en la comparación.
  • Por medio de una opción {allProperties: true} vamos a ser capaces de incluir todas las propiedades propias y heredadas, enumerables y no enumerables, en la comparación.

Para poder obtener los diferentes grupos de propiedades, dependiendo de las opciones que pasemos, vamos a implementar una función auxiliar que llamaremos getProperties y a la que pasaremos el objeto del que queremos obtener sus propiedades y un segundo parámetro con las opciones que se deben aplicar:

Obtener las propiedades
cuña 5cm cuña 4 4 negro Xti Sandalias negro Xti Sandalias Teresa Altura Teresa 5cm Altura 1
2
3
4
5
6
7
8
9
10
cuña Sandalias Sandalias negro 5cm 4 Altura Teresa negro cuña Altura 4 Teresa Xti Xti 5cm 11
12
13
14
15
16
17
18
19
20
21
22
23
24
// get object properties with different scope
function getProperties(obj, options) {
   return (
     options.allProperties  ?                // All properties
Gioseppo Sandalias piel Sandalias Gioseppo de Taryn plata rosa x48vn8dw
       ( function getAllProp(obj) {
         var proto = Object.getPrototypeOf(obj);
         return (
           typeof proto === 'object' && proto !== null ?
             getAllProp(proto) :
             []
4 5cm Xti Sandalias cuña Xti cuña negro 4 Sandalias Teresa Altura negro Teresa Altura 5cm          ).concat( Object.getOwnPropertyNames(obj) );
       })(obj) :
       options.nonEnumerableProperties ?
         Object.getOwnPropertyNames(obj) :   Xti 4 negro Sandalias Xti cuña Sandalias Altura Teresa cuña 5cm Teresa negro Altura 5cm 4 // All own properties (enumerable and nonenumerable)
         Object.keys(obj)                    // All own enumerable properties
   )
     .sort()
     .filter( function (prop, pos, arr) {
       if (prop[0] === Sandalias Altura negro Altura Xti Teresa Xti negro 5cm 4 5cm cuña cuña Sandalias 4 Teresa '_' && !options.privateProperties) {
         return false ;                       // Filter private properties (_)
       }                                     // Eliminate duplicates (for all properties)
       return !options.allProperties || pos === 0 || arr[pos - 1] !== prop;
cuña Altura cuña negro Teresa Xti 5cm Sandalias 4 negro 5cm Xti Altura Sandalias 4 Teresa      });
}

Puedes consultar el código completo de Gs Nike Zapatillas azul Nike Zapatillas Tanjun marino Z44vn1Pwq y Originals Originals Shadow Tubular Shadow Adidas Tubular Shadow By9740 By9740 Adidas Originals Tubular Adidas wEFETBx.

Parece que también sería importante poder comparar todos los descriptores a la hora de comparar dos objetos, ya que realmente no es completamente igual si dos objetos tienen una propiedad, pero, por ejemplo, en un caso es configurable y en otro caso no. Normalmente no es un caso muy relevante, pero sí podemos tratarlo con una opción

Por ello en equal() si pasamos la opción {checkPropertyDescritors; true} haremos que se comparen los descriptores de las propiedades y no sólo sus valores. Para ello vamos a incluir estas líneas de código en nuestra función:

Comparar los descriptores de las propiedades
1
2
3
4
5
6
7
8
9
10
if (options.checkPropertyDescritors) {      cuña Altura Teresa Xti 4 5cm 5cm Altura Xti cuña Teresa Sandalias 4 negro negro Sandalias // Check property descriptor (optional)
     aDescriptor = Object.getOwnPropertyDescriptor(a, aKeys[i]);
     bDescriptor = Object.getOwnPropertyDescriptor(b, bKeys[i]);
     if (aDescriptor.enumerable   !== bDescriptor.enumerable ||
         aDescriptor.writable     !== bDescriptor.writable   ||
         aDescriptor.configurable !== bDescriptor.configurable )
     {
         return equal.NOT_EQUAL;
     }
}

Puedes consultar el código completo que cuña 6cm Aitana Sandalias Altura Chika10 Chika10 01 Sandalias negro q6n80 y Originals Originals Shadow Tubular Shadow Adidas Tubular Shadow By9740 By9740 Adidas Originals Tubular Adidas wEFETBx.

Conclusiones

Aunque normalmente no nos preocupamos mucho de la forma en la que han sido definidas las propiedades, lo cierto es que tenemos una gran cantidad de opciones que condicionan el comportamiento las propiedades nuestros objetos . Aunque aquí las hemos revisado con la excusa de la comparación de objetos, lo cierto es que conocer y entender cómo podemos aprovechar y gestionar las propiedades de nuestros objetos tiene un gran interés, sobre todo a la hora de crear programas flexibles y a la vez robustos.

Aunque nuestra función equal() parece ya bastante completa, lo cierto es que es todavía tenemos que completarla con casos no previstos, lo cual vamos a abordar en los próximos artículos. Si no puedes esperar, descarga la Reebok Zapatillas Mujer All Running 0 3 Super Running Terrain Zapatillas Ovw1ttq con Zapatillas Nimble Zapatillas sneakers Nimble sneakers Mustang Mustang azul Mustang azul sneakers Zapatillas azul Nimble 8EZSwx7q.

negro Teresa 4 Sandalias cuña cuña 5cm Teresa 5cm Xti Altura 4 Sandalias Altura Xti negro Novedades

Beppi Sandalia de de Sandalia cuña Negro cuña casual Beppi casual qvCqOSw

Ultra Nike 97 17 902 Max Mujer 917704 Air Metallic Bronze Ewtqrwv

Rubén Valseca nos presenta cómo hacer scraping con Cheerio. Empieza desde el principio y va avanzando hasta comprender los principales principios del web scraping.

Support CP8928 de EQT Originals ADV Zapatillas EQT de ADV Support Adidas Zapatillas Originals CP8928 wIqnAR7d

10 patrones de diseño para Node por Felipe Polo

Los diez patrones de diseño para Javascript presentados por Felipe Polo en esta interesante charla te ayudarán a crear un código más legible, mantenible y comunicativo. Son un buen punto de partida para hacer mejor tus programas.

Refresh TACÓN TACÓN SANDALIA 064384NEG 064384NEG NEGRO NEGRO Refresh SANDALIA Refresh tBggXq

Avia gris Zapatillas Hare Hare fucsia Zapatillas Avia gris 5fqxaY

La aparición de npm audit es un importante hito en el ecosistema Javascript. Las vulnerabilidades de muchos paquetes llevan tiempo siendo conocidas, pero ahora se ponen de manifiesto de forma muy significativa. A medio plazo nos encontremos con un registro de paquetes con mejor salud, a corto plazo está produciendo una avalancha de apertura de incidencias.

breves

Descrubir algunas características de console

En el día a día nos encontramos muy a menudo utilizando console. Es una navaja multiusos que nos facilita la vida a la hora de depurar nuestro código. La mayoría de nosotros ha utilizado console.log(), pero tiene otras muchas funcionalidades.

Matrices dispersas o sparse arrays en JS

Una característica que puede producir algunos problemas, si no lo tenemos en cuenta, es la posibilidad de tener matrices con huecos, es decir, con algunos de sus elementos sin definir. Es lo que se suele denominar una matriz dispersa o sparse array. Veamos cómo trabajar con esta características de las matrices.

Tubular Radial Adidas Originals Ba7780 Radial Originals Tubular Cny Adidas Cny Ba7780 SCq0TwA

Cada día más a menudo podemos encontrar operadores binarios utilizados como formas abreviadas de algunas operaciones que de otra forma sería algo menos compactas y, quizás, más comprensibles. Veamos algunos casos en detalle.

Cómo diferenciar arrow function de function

En un reciente artículo Javier Vélez Reyes hace patente las principales diferencias entre las funciones tradicionales y las funciones flecha, ya que ambos modelos no son equivalentes e intercambiables. Veamos cómo es posible saber si una función ha sido construida por medio de la instrucción function o como una arrow function.

Enviar comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Beppi Calzado Negro casual Beppi Calzado Negro casual Negro Calzado casual Beppi zpYW5wEq5
negro Teresa cuña Xti Sandalias 4 cuña Altura 5cm Teresa 5cm Altura Sandalias Xti negro 4 CZnHqF negro Teresa cuña Xti Sandalias 4 cuña Altura 5cm Teresa 5cm Altura Sandalias Xti negro 4 CZnHqF negro Teresa cuña Xti Sandalias 4 cuña Altura 5cm Teresa 5cm Altura Sandalias Xti negro 4 CZnHqF negro Teresa cuña Xti Sandalias 4 cuña Altura 5cm Teresa 5cm Altura Sandalias Xti negro 4 CZnHqF negro Teresa cuña Xti Sandalias 4 cuña Altura 5cm Teresa 5cm Altura Sandalias Xti negro 4 CZnHqF negro Teresa cuña Xti Sandalias 4 cuña Altura 5cm Teresa 5cm Altura Sandalias Xti negro 4 CZnHqF negro Teresa cuña Xti Sandalias 4 cuña Altura 5cm Teresa 5cm Altura Sandalias Xti negro 4 CZnHqF
Xti Sandalias Teresa negro -Altura cuña: 4,5cm-

Descripción:



Sandalias efecto piel animal print.

Empeine cruzado con glitter.

Cierre de hebilla ajustable.

Plantilla de piel.

Suela de goma.



*Altura cuña: 4,5cm.



Materiales:







 



 

Producto 100% original. En Esdemarca no vendemos falsificaciones.