Возможно ли достичь динамического определения объема в JavaScript, не прибегая к eval?

JavaScript имеет лексическую область видимости, что означает, что нелокальные переменные, к которым обращаются из функции, преобразуются в переменные, присутствующие в родителях ». объем этой функции, когда она была определена. Это в отличие от динамической области видимости, в которой нелокальные переменные, доступ к которым осуществляется из функции, преобразуются в переменные, присутствующие в области вызова этой функции при ее вызове.

<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>

Вышеприведенная программа печатает 1 и затем 2 на языке с лексической областью, и она печатает 3 и затем 1 на языке с динамической областью. Так как JavaScript имеет лексическую область видимости, он напечатает 1, а затем 2, как показано ниже:

<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>

Хотя JavaScript не поддерживает динамическую область видимости, мы можем реализовать ее, используяeval следующее:

<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>

Я хотел бы знать, существует ли другой возможный способ достижения того же результата, не прибегая кeval.

Edit: Это то, что я пытаюсь реализовать без использованияeval:

<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>

Я знаю, что это не очень хороший пример, но общая идея состоит в том, чтобы использовать динамическую область видимости для создания замыканий. Я думаю, что эта модель имеет большой потенциал.

Ответы на вопрос(7)

Ваш ответ на вопрос