Возможно ли достичь динамического определения объема в 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>
Я знаю, что это не очень хороший пример, но общая идея состоит в том, чтобы использовать динамическую область видимости для создания замыканий. Я думаю, что эта модель имеет большой потенциал.