Seleccionar página
Cómo hemos podido observar en Propiedades propias o heredadas en los objetos y Propiedades enumerables y no enumerables, Javascript define un conjunto de condiciones que definen que resultado obtendremos con los diferentes métodos que tenemos para obtener la propiedades de un objeto.

  • for in obtiene las propiedades enumerables propias o heredadas del objeto y no obtiene las propiedades no enumerables.
  • Object.getOwnPropertyNames(objeto) obtiene las propiedades enumerables y no enumerables propias del objeto y no obtiene las propiedades heredadas.

  • Object.keys(objeto) obtiene las propiedades enumerables propias del objeto y no las propiedades no enumerables o aquellas que siendo enumerables son heredadas por la cadena de prototipos.

Parece un galimatías, pero es más sencillo de lo que parece. Hay un interesante cuadro al final de esta página de MDN donde se muestra las diferentes situaciones.

Pero, ¿cómo podemos obtener absolutamente todas las propiedades de un objeto? No disponemos de un método nativo para este propósito, pero en unas pocas lineas podemos conseguir una función para nuestro propósito.

function getPropertyNames(obj) {
    var proto = Object.getPrototypeOf(obj);
    return (
        (typeof proto === 'object' && proto !== null ? getPropertyNames(proto) : [])
        .concat(Object.getOwnPropertyNames(obj))
        .filter(function(item, pos, result) { return result.indexOf(item) === pos; })
        .sort()
    );
}

Esta compacta función permite obtener todos las propiedades efectivas de un objeto, sean o no enumerables, sean propias o heredadas. Paso a paso, esta función:

  • obtiene el prototipo del objeto por medio de Object.getPrototypeOf(obj) (función de EMCAScript 5.1 que está disponible el la mayoría de los entornos, incluido IE9 en adelante)
  • si existe el prototipo se llama recursivamente a la función
  • se obtienen una matriz con las propiedades enumerables y no enumerables propias del objeto por medio de Object.getOwnPropertyNames(obj)
  • se filtra la matriz para eliminar duplicados
  • se ordena la matriz

Vamos a ver varios ejemplos de utilización de getPropertyNames(). En este primer caso se consultan las propiedades de un objeto construido como literal y se obtienen las propiedades de Object y las propiedades definidas en el objeto.

var o = {
    a: 1, b: 2, c: 3
};
console.log(getPropertyNames(o));
// Mostrará más o menos
// [ '__defineGetter__',
//   '__defineSetter__',
//   '__lookupGetter__',
//   '__lookupSetter__',
//   '__proto__',
//   'a',
//   'b',
//   'c',
//   'constructor',
//   'hasOwnProperty',
//   'isPrototypeOf',
//   'propertyIsEnumerable',
//   'toLocaleString',
//   'toString',
//   'valueOf' ]

Si se utiliza una función como constructor de un objeto se obtendrá igualmente las propiedades de Object y las propiedades definidas en el constructor con this.

function Person(firstname, lastname, birthday) {
        this.firstname = firstname;
        this.lastname = lastname;
}
var p = new Person('Pablo', 'Almunia', '07-08-1966');
console.log(getPropertyNames(p));
// Mostrará más o menos
// [ '__defineGetter__',
//   '__defineSetter__',
//   '__lookupGetter__',
//   '__lookupSetter__',
//   '__proto__',
//   'birthday',
//   'constructor',
//   'firstname',
//   'hasOwnProperty',
//   'isPrototypeOf',
//   'lastname',
//   'propertyIsEnumerable',
//   'toLocaleString',
//   'toString',
//   'valueOf' ]

Si se utilizan clases y herencia de ECMAScript 6 nuestra pequeña función sigue devolviendo todas las propiedades definidas en los constructores, las definidas por medio de get o set, tanto de la clase instanciada como de todas las clases de las que se hereda.

class Person {
    constructor(firstname, lastname, birthday) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.birthday = new Date(birthday);
    }
    get age() {
        var ageDifMs = Date.now() - this.birthday.getTime();
        var ageDate = new Date(ageDifMs);
        return Math.abs(ageDate.getUTCFullYear() - 1970);
    }
}
class Employee extends Person {
    constructor(firstname, lastname, birthday, position) {
        super(firstname, lastname, birthday);
        this.position = position;
    }
}
var p = new Employee('Pablo', 'Almunia', '07-08-1966', 'Architect');

console.log(getPropertyNames(p));
// Mostrará más o menos
// [ '__defineGetter__',
//   '__defineSetter__',
//   '__lookupGetter__',
//   '__lookupSetter__',
//   '__proto__',
//   'age',
//   'birthday',
//   'constructor',
//   'firstname',
//   'hasOwnProperty',
//   'isPrototypeOf',
//   'lastname',
//   'position',
//   'propertyIsEnumerable',
//   'toLocaleString',
//   'toString',
//   'valueOf' ]

Es cierto que en muchas ocasiones nos bastará con utilizar for in, Object.getOwnPropertyNames(objeto) o Object.keys(objeto), pero esta pequeña y sencilla función nos permite obtener en cualquier momento una matriz con todas las propiedades de un objeto, sin excepción.

Si quieres conocer más sobre la cadena de prototipos y conocer que clases han a portado cada una de las propiedades, consulta cómo inspeccionar la herencia en Javascript.

Novedades

HTTP2 para programadores. Enviar mensajes del servidor al cliente con Server Sent Event (sin WebSockets)

HTTP2 para programadores. Enviar mensajes del servidor al cliente con Server Sent Event (sin WebSockets)

En esta charla, organizada por MadridJS, Pablo Almunia nos muestra cómo la mayoría de nosotros cuando oímos hablar por primera vez de HTTP2 nos ilusionamos con las posibilidades que presumiblemente se abrían para el desarrollo de soluciones web avanzadas y cómo muchos nos sentimos defraudados con lo que realmente se podía implementar.

En esta charla podemos ver cómo funciona el HTTP2, que debemos tener en cuenta en el servidor para hace uso de este protocolo y, sobre todo, cómo podemos enviar información desde el servidor al cliente de forma efectiva y fácil. Veremos con detenimiento cómo por medio de los Server-Sent Events (SSE) podemos recibir en el cliente datos enviados desde el servidor sin utilizar websocket, simplificando enormemente la construcción de aplicaciones con comunicación bidireccional.

Observables en Javascript con Proxies

Observables en Javascript con Proxies

En esta charla, organizada por MadridJS, Pablo Almunia nos habla de la observación reactiva de objetos en Javascript por medio de Proxy. Se describe paso a paso cómo funcionan los Proxies y en que casos pueden ser nuestro mejor aliado. Veremos que no hay que tenerles miedo, son bastante sencillos de utilizar, y nos ofrecen una gran abanico de posibilidades.

Aplicaciones JAMStack, SEO friendly y escalables con NextJS

Aplicaciones JAMStack, SEO friendly y escalables con NextJS

En esta charla de Madrid JS, Rafael Ventura nos describe las funcionalidades clave de NextJS, nos muestra en vivo cómo desarrollar una completa aplicación JAMStack con Server Side Rendering (SSR) y Static Site Generation (SSG) y termina mostrando como publicar esta aplicación en Vercel.

Stencil JS: mejora el Time To Market de tu producto, por Rubén Aguilera

Stencil JS: mejora el Time To Market de tu producto, por Rubén Aguilera

En esta charla Rubén Aguilera nos cuenta los problemas que tienen muchas empresas a la hora de sacar productos accesibles, vistosos y usables en el Time To Market que requiere Negocio y cómo podemos minimizar este tiempo gracias al DevUI con StencilJS para adecuar una aplicación de Angular a las exigencias del mercado en tiempo record.

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.

Operadores de bits usados con asiduidad

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.