¿Es posible lograr un alcance dinámico en JavaScript sin tener que recurrir a eval?

JavaScript tiene un alcance léxico, lo que significa que las variables no locales a las que se accede desde dentro de una función se resuelven en las variables presentes en el alcance de los padres de esa función cuando se definió. Esto contrasta con el alcance dinámico en el que las variables no locales a las que se accede desde dentro de una función se resuelven en las variables presentes en el alcance de llamada de esa función cuando se llama.

<code>x=1
function g () { echo $x ; x=2 ; }
function f () { local x=3 ; g ; }
f # does this print 1, or 3?
echo $x # does this print 1, or 2?
</code>

El programa anterior imprime 1 y luego 2 en un lenguaje de ámbito léxico, e imprime 3 y luego 1 en un idioma de ámbito dinámico. Dado que JavaScript tiene un alcance léxico, imprimirá 1 y luego 2 como se muestra a continuación:

<code>var print = x => console.log(x);

var x = 1;

function g() {
    print(x);
    x = 2;
}

function f() {
    var x = 3;
    g();
}

f();           // prints 1

print(x);      // prints 2</code>

Aunque JavaScript no es compatible con el alcance dinámico, podemos implementarlo usandoeval como sigue:

<code>var print = x => console.log(x);

var x = 1;

function g() {
    print(x);
    x = 2;
}

function f() {
    // create a new local copy of `g` bound to the current scope
    // explicitly assign it to a variable since functions can be unnamed
    // place this code in the beginning of the function - manual hoisting
    var g_ = eval("(" + String(g) + ")");
    var x = 3;
    g_();
}

f();                         // prints 3

print(x);                    // prints 1</code>

Me gustaría saber si existe otra forma posible de lograr el mismo resultado sin recurrir aeval.

Editar: Esto es lo que estoy tratando de implementar sin usareval:

<code>var print = x => console.log(x);

function Class(clazz) {
    return function () {
        var constructor;
        var Constructor = eval("(" + String(clazz) + ")");
        Constructor.apply(this, arguments);
        constructor.apply(this, arguments);
    };
}

var Rectangle = new Class(function () {
    var width, height;

    constructor = function (w, h) {
        width = w;
        height = h;
    };

    this.area = function () {
        return width * height;
    };
});

var rectangle = new Rectangle(2, 3);
print(rectangle.area());</code>

Sé que no es un buen ejemplo, pero la idea general es usar el alcance dinámico para crear cierres. Creo que este patrón tiene mucho potencial.

Respuestas a la pregunta(7)

Su respuesta a la pregunta