Have the scope accessible as an object and implement a new with operator / block
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.
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.
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.
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.
Well what about you add an if that checks whether scope is used or not and if it is disables these optimizations?
In a way it would be like proxies: slow if used but doesn't change anything if you don't use them.
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.)
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:
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?