Seleccionar página

classes

por Javier Vélez Reyes

En general creo que buscar encapsulación en vez de protección de información en JavaScript es un error importante. Pero este debate prefiero moverlo a otro post que en el hablaré lo que yo llamo Efecto ornitorrinco.

Al respecto a la encapsulación en las clases de ES6 varias puntualizaciones.

1. En general JavaScript no persigue dar soporte a la encapsulación. Es cierto que dentro del modelo de introspección proporciona mecanismos para definir propiedades no enumerables o de solo lectura pero en general tanto estas como a las capacidades de congelación y prevención que operan a nivel de objetos se entienden como un antipatrón. Esto está alineado con la concepción de los lenguajes dinámicos que priman flexibilidad ante seguridad entendiendo que se opera sobre el principio de protección de la información.

2. La existencia de métodos get/set incluida en ES5 no tiene como propósito definir modelos de encapsulación sino poder incluir lógicas de tratamiento para la gestión del acceso a propiedades en modo de lectura o escritura. En concreto get permite incluir lógica para decorar un acceso a dato o implementar un atributo derivado mientras que set permite inyectar lógica de protección semántica ante operaciones de escritura. Sin embargo el soporte se preveé que se desarrolle sobre atributos «públicos» (dicho en cultura Java).

3. Existen varias maneras de simular encapsulación en JavaScript. Como reconoce Alex Fernández (@pinchito), las clausuras son la forma más natural dada la pragmática de uso del lenguaje. Si bien no son de aplicación en todo contexto arquitectónico. Por ejemplo en Polymer se hace imposible articular encapsulación vía clausura ya que, por construcción arquitectónica, el framework eleva las variables de retención léxica al nivel de prototipo convirtiéndolas en atributos de clase (las variables estáticas en cultura Java). Para salvar esta problemática en general se reconocen dos alternativas clásicas que entroncan con actividades de metaprogramación.

A. Creas un único objeto _data (definido privadamente si quieres) y recontextualizas para cada método publico del objeto, el this para que apunte al objeto _data (por medio del uso de bind por ejemplo). De esta manera, _data contendrá una representación privada de todo tu estado interno:

function hide (obj) {
   var ctx = {};
   var out = {};
   Object.keys(obj).forEach (function (k) {
     if (typeof (obj[k]) === 'function') {
          mp.copy (out, obj, k);
          mp.bind (out, k, ctx);
     }
     else mp.copy (ctx, obj, k);
   });
   return out;
}

B. La segunda variante consiste en hacer eso mismo pero generando un proxy por delante. Copias los métodos públicos del objeto que quieras proteger en otro objeto inicialmente vacío contextualizando sus this para que apunte al método delegado. Después entregas al cliente sólo el objeto de proxy que contiene solo la interfaz pública del objeto:

function proxify (obj) {
   var out = {};
   Object.keys(obj).forEach (function (k) {
     if (typeof (obj[k]) === 'function')
         mp.forward (out, obj, k);    
   });
   return out;
}

Donde los métodos copy, bind & forward son autodescriptivos. Los copio a continuación aunque pueden verse en Github:

mp = {};
mp.bind = function bind (core, key, ctx) {

    if (typeof (core[key]) === 'function')
        core[key] = core[key].bind(ctx);
    return core;
    
};
mp.copy = function copy (core, ext, key) {

    if (key in ext)
        mp.add (core, key, ext[key]);
    return core;

};
mp.add = function add (core, key, value) {

    core[key] = value;
    return core;
    
};
mp.forward = function forward (core, ext, key) {
    
    return mp.outerDelegate (core, ext, key, ext);
    
};
mp.outerDelegate = function outerDelegate (core, ext, key, ctx) {
    
    var context = ctx || ext;
    core[key] = function () {
        var args = [].slice.call (arguments);
        var out  = ext[key].apply (context, args);
        return out === ext ? this : out;
    };
    return core;
    
};

Ambos códigos operan en ES5. De la segunda técnica se puede hacer una implementación equivalente en ES6 utilizando la propuesta de objetos Proxy. Estas y otras técnicas de programación las cuento en mi charla de metaprogramación:

Diapositivas en slideshare

Contenido en Github

JavierVelezJavier Vélez Reyes
Ph. D. Computer Science
@javiervelezreye

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.