Have the scope accessible as an object and implement a new with operator / block

# Xavier MONTILLET (14 years ago)

There is this one thing in JavaScript I really hate: You can't so {{$varName}} as in PHP so as soon as you need dynamic names, you have to put everything in an object...

I don't know how scopes are implemented but there should be a "not so hard" way to make them available as JS objects. The same way window (or global or self or whatever) works for the global scope. Something like this:

var a = { }; var b = [ ]; window[ 'a' ] === a;// true window[ 'b' ] === b;// true ( function ( ) { var a = { }; var b = [ ]; scope[ 'a' ] === a;// -> true scope[ 'b' ] === b;// -> true }( ) );

And the scope would inherit the parent scope. Here (this code would be "inside the function":

var scope = Object.create( window, { a: { value: a, enumerable: true, writable: true, configurable: true }, // same with b } );

About the properties:

  • enumerable true seems obvious
  • writable too, except for variable declared with const
  • configurable, I'd say false since you cannot use delete on variables declared with var. But if you want the same behavior as window, then variables declared with var would have configurable=false and the ones declared as properties of the scope would have configurable=true.

var a = { }; window.b = { }; console.log( delete a );// false console.log( delete b );// true console.log( a );// Object console.log( b );// ReferenceError: b is not defined

I always though this behavior was strange but since it is and doesn't bother anyone...

About security, maybe Object.getPrototypeOf should throw an error on scopes. Because having a child scope change your variables could be strange... But that would only be a problem for scripts made with third-party scripts included in own scripts that declare "fake" variables to remove access to some features:

( function ( ) { var window, setTimeout, undefined; ( function ( ) {// this function is from third party. It got inserted in this code to make it "safer" // whatever but can't access setTimeout ).call( undefined ); }( ) );

And without Object.getPrototypeOf and scope:

( function ( ) { var window, setTimeout, undefined; ( function ( ) {// this function is from third party. It got inserted in this code to make it "safer" Object.getPrototypeOf( Object.getPrototypeOf( scope ) ).setTimeout( function( ) { }, 100 );// you can access setTimout ).call( undefined ); }( ) );

This might not seam that useful but when you think about the with "operator" from ES 3, if you add this scope thing, it becomes easy to make it work "properly".

I don't know how we could call it but what it would do is setting the "inner" scope to an object. So ALL "variables" in that block would be the object's properties and it would "remove" any other variable.

Here is an example:

( function ( ) { var a = 'a'; var b = 'b'; var o = { b: 'B', c: 'C' }; // here, scope == { a: 'a', b: 'b', o: { b: 'B', c: 'C' } } with ( o ) { // /!\ scope is still the same! // otherwise you would have no access to "real" variables b;// 'B' c;// 'C' try { a; } catch ( e ) { e;// ReferenceError: a is not defined } scope.a;// 'a' scope.b;// 'b' scope.c;// undefined } } )( );

What do you think?

# Erik Corry (14 years ago)

2011/12/20 Xavier MONTILLET <xavierm02.net at gmail.com>:

Hi,

There is this one thing in JavaScript I really hate: You can't so {{$varName}} as in PHP so as soon as you need dynamic names, you have to put everything in an object...

I don't know how scopes are implemented

Not being able to get hold of the scope as an object enables important optimizations and is a feature, not a bug.

# Xavier MONTILLET (14 years ago)

What kind of optimizations? The variable have to be in some kind of structure and it should be possible to read it as an object the same way you read it as variables...

The fact that the "inheritance" between scopes I spoke of would be hard to implement because they keep a one level deep structure and change it when they change scope would be understandable. But no being able to read the structure seems strange to me.

# Axel Rauschmayer (14 years ago)

I would love to have something like Python’s locals(): docs.python.org/py3k/library/functions.html#locals

It would not allow modifications, but it would still be very useful.

# Andreas Rossberg (14 years ago)

On 20 December 2011 11:24, Xavier MONTILLET <xavierm02.net at gmail.com> wrote:

What kind of optimizations?

Optimizations such as putting variables in registers, putting variables on the stack, overlaying variables with disjoint life times, eliminating some variables entirely, minimizing closure environments, to name just a few.

# Xavier MONTILLET (14 years ago)

Well what about you add an if that checks whether scope is used or not and if it is disables these optimizations?

# Xavier MONTILLET (14 years ago)

In a way it would be like proxies: slow if used but doesn't change anything if you don't use them.

# Andreas Rossberg (14 years ago)

On 20 December 2011 11:51, Xavier MONTILLET <xavierm02.net at gmail.com> wrote:

Well what about you add an if that checks whether scope is used or not and if it is disables these optimizations?

That's what's done for things like the `arguments' object. And it's an ugly mess, in terms of semantics as well as implementation. I believe it's fair to say that it is widely considered a misfeature these days. (ES is moving away from it, as well as from the global object.)