Implementación de let en ES5?

Iniciado por @XSStringManolo, 16 Diciembre 2019, 17:22 PM

0 Miembros y 1 Visitante están viendo este tema.

@XSStringManolo

Probé con Babel y la versión que me crea es usando variables con la barra baja para declarar dos variables distintas e "indicar" que una de ellas es privada. Pero sigue siendo accesible públicamente. No debería utilizar un WeakMap?

Si conoceis la implementación de let estaría genial para poder utilizarla en ES5.


ES6+
Código (javascript) [Seleccionar]
for(let x = 0; x < 10; ++x)
{
alert(x);
}
let x = 12;
alert(x);


Versión ES5 generada por Babel
Código (javascript) [Seleccionar]
for(var _x = 0; _x < 10; ++_x)
{
alert(_x);
}
var x = 12;
alert(x);

MinusFour

#1
Lo hace para ahorrarse una función. En ES5 la única forma de crear nuevos contextos es a través de funciones. Lo que está haciendo babel ahí únicamente es evitar una colisión entre variables, no tiene nada que ver con que sea privada o no.

Código (javascript) [Seleccionar]

(function(){
  for(var x = 0; x < 10; ++x){
      alert(x);
  }
}).call(this);

var x = 12;
alert(x);


Edit: Y es importante mencionar que babel trabaja otros scenarios dependiendo del código. Por ejemplo, cada ciclo tiene su propia instancia de "x", así que lo mete dentro de una función si tiene funciones anidadas.

@XSStringManolo

A esta pattern se le llama proxied? .call es el método interno [[call]] y al utilizar this se referencia a la función anónima no? Cleaver!
La vi anteriormente para sobrescribir window.alert, andaba buscando como sobrescribirla para substituirla por un componente.

Qué forma más curiosa la de babel. Parece que optimiza la cantidad de código en vez de la performnce no?

Muchas gracias!

MinusFour

Cita de: @?0!,5^34 en 17 Diciembre 2019, 00:25 AM
A esta pattern se le llama proxied? .call es el método interno [[call]] y al utilizar this se referencia a la función anónima no? Cleaver!
La vi anteriormente para sobrescribir window.alert, andaba buscando como sobrescribirla para substituirla por un componente.

Qué forma más curiosa la de babel. Parece que optimiza la cantidad de código en vez de la performnce no?

Muchas gracias!

Es una IIFE, solo que use call para invocarla.  Realmente, en ese código no es necesario usar call. Lo pongo ahí nada más porque puede ser necesario dependiendo del caso.

Por ejemplo:

Código (javascript) [Seleccionar]

let obj = { sum : 0 };
obj.fn = function(){
    for(let i = 0; i < 5; i++){
        this.sum += i;
    }
    console.log(obj.sum); //10
}

obj.fn();


Y si haces lo que yo hice sin el call:

Código (javascript) [Seleccionar]

let obj = { sum : 0 };
obj.fn = function(){
    (function(){
        for(var i = 0; i < 5; i++){
            this.sum += i;
        }
    })();
    console.log(obj.sum); //0
}

obj.fn();


Y con el call te daría 10. Las IIFEs no heredan el contexto de this y tampoco puedes usar una función flecha porque no existían en ES5. Hay otros casos que también tienes que recordar para que este como lo dice el estándar.

Babel se salta algunas cosas en el estandar ya sea por razones de rendimiento o porque simplemente no lo pueden hacer sin tener un runtime de JS en JS. Por lo general trata de apegarse lo más que pueda al estándar.

@XSStringManolo

No hereda el contexto porque se evalua antes? Se evalua de dentro hacia fuera?

Muchas gracias! Se ve my interesante!

MinusFour

#5
Cita de: @?0!,5^34 en 17 Diciembre 2019, 01:51 AM
No hereda el contexto porque se evalua antes? Se evalua de dentro hacia fuera?

Muchas gracias! Se ve my interesante!

No lo hereda porque el contexto del objeto de una llamada se determina en la invocación de la función (en el caso de funciones regulares). Solo en el caso de funciones flecha es que el contexto del objeto se "hereda" (hay una explicación un poco más larga).

El contexto del objeto es básicamente lo que va detrás de la función o metodo.

Código (javascript) [Seleccionar]

  obj.fn();
// ^
//contexto


Código (javascript) [Seleccionar]

       fn();
//^
//no hay contexto
//a menos que sea una función resultante de bind
//misma situación para IIFEs


Código (javascript) [Seleccionar]

  fn.call(obj);
//         ^
//         contexto

@XSStringManolo

Cita de: MinusFour en 17 Diciembre 2019, 02:05 AM
No lo hereda porque el contexto del objeto de una llamada se determina en la invocación de la función (en el caso de funciones regulares). Solo en el caso de funciones flecha es que el contexto del objeto se "hereda" (hay una explicación un poco más larga).

El contexto del objeto es básicamente lo que va detrás de la función o metodo.

Código (javascript) [Seleccionar]

  obj.fn();
// ^
//contexto


Código (javascript) [Seleccionar]

       fn();
//^
//no hay contexto
//a menos que sea una función resultante de bind
//misma situación para IIFEs


Código (javascript) [Seleccionar]

  fn.call(obj);
//         ^
//         contexto

Ahhh vale! Pensé que era por otra cosa xD.