Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to achieve dynamic scoping in JavaScript without resorting to eval?

JavaScript has lexical scoping which means that non-local variables accessed from within a function are resolved to variables present in the parents' scope of that function when it was defined. This is in contrast to dynamic scoping in which non-local variables accessed from within a function are resolved to variables present in the calling scope of that function when it is called.

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? 

The above program prints 1 and then 2 in a lexically scoped language, and it prints 3 and then 1 in a dynamically scoped language. Since JavaScript is lexically scoped it will print 1 and then 2 as demonstrated below:

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

Although JavaScript doesn't support dynamic scoping we can implement it using eval as follows:

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

I would like to know if there exists another possible way to achieve the same result without resorting to eval.

Edit: This is what I'm trying to implement without using eval:

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());

I know that it's not a very good example but the general idea is to use dynamic scoping to create closures. I think this pattern has a lot of potential.

like image 813
Aadit M Shah Avatar asked Apr 08 '12 06:04

Aadit M Shah


People also ask

What is the problem with dynamic scoping?

In general, dynamic scoping violates modularity and information hiding, because it makes the meaning of an operation depend on where it's called from. One advantage of dynamic scoping is that the variables are implicitly visible by subprograms and do not need to be passed as parameters.

What is dynamic scoping in JavaScript?

In dynamic scoping, you search in the local function first, then you search in the function that called the local function, then you search in the function that called that function, and so on, up the call-stack.

Which are the approaches used to implement dynamic scope?

Each time a new function is executed, a new scope is pushed onto the stack. Perl supports both dynamic and static scoping. Perl's keyword “my” defines a statically scoped local variable, while the keyword “local” defines a dynamically scoped local variable.

What is the difference between lexical scoping and dynamic scoping?

Answer. Lexical scoping refers to when the location of a function's definition determines which variables you have access to. On the other hand, dynamic scoping uses the location of the function's invocation to determine which variables are available.


1 Answers

To add a note on this topic:

In JavaScript whenever you make use of:

  • function declaration statement or function definition expression then local variables will have Lexical Scoping.

  • Function constructor then local variables will refer to the global scope (top-level code)

  • this is the only built-in object in JavaScript that has a dynamic scoping and is set through the execution (or invocation) context.

So to answer to your question, In JS the this is already dynamically scoped feature of the language and you even don't need to emulate another one.

like image 116
Arman Avatar answered Sep 21 '22 19:09

Arman