Fwd: Indirect references to variables

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Fwd: Indirect references to variables

John Gardner
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Indirect references to variables

Frankie Bagnardi
This is a common situation, but one easily solved by object literals. Reflecting on the scope is confusing and would hurt tooling (it's essentially eval).

```js
var mapping = {Polygon: Polygon};
var meshClass = mapping[ajaxData.className];
```




On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[hidden email]> wrote:
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Indirect references to variables

Bergi
In reply to this post by John Gardner
John Gardner schrieb:
> ECMAScript currently offers no clean way to "dereference" a variable in the
> current scope.

There is one. It's called `eval`.

> A hacky workaround is to create an anonymous function that simply returns a
> reference to the named variable:
>
>      function dereference(name){
>          return new Function([], "return " + name)();
>      }
>      dereference("Paintbrush") === Paintbrush; // true

Actually that does only work with global variables as well, quite like
the property access on the global object.

> Another approach
> might be to leverage `eval`, which opens up the obvious issues of
> performance and security.

And so does your proposed backslash operator.
The only difference I can see would be that you are wishing to
`eval`uate only identifier references not arbitrary expressions, but
*that* can be trivially dealt with by testing the expression to match
the Identifer production. A regex could do that.
Neither performance nor security would be any better though.

The preferred way of what you are trying to do is to whitelist the
classes you want to make available, and by naming/aliasing them
explicitly. Basically

     var classReference = {Paintbrush, …}[className];
     var instance = new classReference();

For additional security, you might want to use an object that doesn't
inherit from `Object.prototype`, or just a `Map` right away.

Regards,
  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Indirect references to variables

John Gardner
In reply to this post by Frankie Bagnardi
Trouble is, if one has literally hundreds of classes or functions that need to be matched, they'd rather not pool them all into one massive object literal for the sake of easier mapping. DRY principle fully relevant.

Also, yes, while it would be a pain for static type analysis, it wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, whereas the indirect references would only point to modifiers only:

    var className = \"doSomethingSinister(/etc/passwd/);"

That line would literally be looking for a property in the current scope that'd be named this:

    global["doSomethingSinister(/etc/passwd/);"]
    window["doSomethingSinister(/etc/passwd/);"]



On 9 December 2015 at 16:09, Frankie Bagnardi <[hidden email]> wrote:
This is a common situation, but one easily solved by object literals. Reflecting on the scope is confusing and would hurt tooling (it's essentially eval).

```js
var mapping = {Polygon: Polygon};
var meshClass = mapping[ajaxData.className];
```




On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[hidden email]> wrote:
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Indirect references to variables

Bradley Meck
Are you putting hundreds of classes into a single scope?

On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <[hidden email]> wrote:
Trouble is, if one has literally hundreds of classes or functions that need to be matched, they'd rather not pool them all into one massive object literal for the sake of easier mapping. DRY principle fully relevant.

Also, yes, while it would be a pain for static type analysis, it wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, whereas the indirect references would only point to modifiers only:

    var className = \"doSomethingSinister(/etc/passwd/);"

That line would literally be looking for a property in the current scope that'd be named this:

    global["doSomethingSinister(/etc/passwd/);"]
    window["doSomethingSinister(/etc/passwd/);"]



On 9 December 2015 at 16:09, Frankie Bagnardi <[hidden email]> wrote:
This is a common situation, but one easily solved by object literals. Reflecting on the scope is confusing and would hurt tooling (it's essentially eval).

```js
var mapping = {Polygon: Polygon};
var meshClass = mapping[ajaxData.className];
```




On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[hidden email]> wrote:
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Indirect references to variables

John Gardner

Only at top-level. This issue actually surfaced when I realised I had no way to indirectly access classes by name... and for some reason, neither the global object nor the eval hack were returning anything. It worked fine for simple variables, so I wondered if that was an intentional side-effect of classes in ECMAScript.

(Of course, if not, it may actually be an issue with V8's implementation...)

On 09/12/2015 5:05 PM, "Bradley Meck" <[hidden email]> wrote:
Are you putting hundreds of classes into a single scope?

On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <[hidden email]> wrote:
Trouble is, if one has literally hundreds of classes or functions that need to be matched, they'd rather not pool them all into one massive object literal for the sake of easier mapping. DRY principle fully relevant.

Also, yes, while it would be a pain for static type analysis, it wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, whereas the indirect references would only point to modifiers only:

    var className = \"doSomethingSinister(/etc/passwd/);"

That line would literally be looking for a property in the current scope that'd be named this:

    global["doSomethingSinister(/etc/passwd/);"]
    window["doSomethingSinister(/etc/passwd/);"]



On 9 December 2015 at 16:09, Frankie Bagnardi <[hidden email]> wrote:
This is a common situation, but one easily solved by object literals. Reflecting on the scope is confusing and would hurt tooling (it's essentially eval).

```js
var mapping = {Polygon: Polygon};
var meshClass = mapping[ajaxData.className];
```




On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[hidden email]> wrote:
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Indirect references to variables

Jordan Harband
Can you not put each class in its own module, and simply require, by name, the one you want?

On Tue, Dec 8, 2015 at 10:19 PM, John Gardner <[hidden email]> wrote:

Only at top-level. This issue actually surfaced when I realised I had no way to indirectly access classes by name... and for some reason, neither the global object nor the eval hack were returning anything. It worked fine for simple variables, so I wondered if that was an intentional side-effect of classes in ECMAScript.

(Of course, if not, it may actually be an issue with V8's implementation...)

On 09/12/2015 5:05 PM, "Bradley Meck" <[hidden email]> wrote:
Are you putting hundreds of classes into a single scope?

On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <[hidden email]> wrote:
Trouble is, if one has literally hundreds of classes or functions that need to be matched, they'd rather not pool them all into one massive object literal for the sake of easier mapping. DRY principle fully relevant.

Also, yes, while it would be a pain for static type analysis, it wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, whereas the indirect references would only point to modifiers only:

    var className = \"doSomethingSinister(/etc/passwd/);"

That line would literally be looking for a property in the current scope that'd be named this:

    global["doSomethingSinister(/etc/passwd/);"]
    window["doSomethingSinister(/etc/passwd/);"]



On 9 December 2015 at 16:09, Frankie Bagnardi <[hidden email]> wrote:
This is a common situation, but one easily solved by object literals. Reflecting on the scope is confusing and would hurt tooling (it's essentially eval).

```js
var mapping = {Polygon: Polygon};
var meshClass = mapping[ajaxData.className];
```




On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[hidden email]> wrote:
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Indirect references to variables

John Gardner

Never mind. This is beginning to south like too much of a damn edge case for it to be of language-wide relevance.

Pretend this discussion never happened.

On 09/12/2015 5:40 PM, "Jordan Harband" <[hidden email]> wrote:
Can you not put each class in its own module, and simply require, by name, the one you want?

On Tue, Dec 8, 2015 at 10:19 PM, John Gardner <[hidden email]> wrote:

Only at top-level. This issue actually surfaced when I realised I had no way to indirectly access classes by name... and for some reason, neither the global object nor the eval hack were returning anything. It worked fine for simple variables, so I wondered if that was an intentional side-effect of classes in ECMAScript.

(Of course, if not, it may actually be an issue with V8's implementation...)

On 09/12/2015 5:05 PM, "Bradley Meck" <[hidden email]> wrote:
Are you putting hundreds of classes into a single scope?

On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <[hidden email]> wrote:
Trouble is, if one has literally hundreds of classes or functions that need to be matched, they'd rather not pool them all into one massive object literal for the sake of easier mapping. DRY principle fully relevant.

Also, yes, while it would be a pain for static type analysis, it wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, whereas the indirect references would only point to modifiers only:

    var className = \"doSomethingSinister(/etc/passwd/);"

That line would literally be looking for a property in the current scope that'd be named this:

    global["doSomethingSinister(/etc/passwd/);"]
    window["doSomethingSinister(/etc/passwd/);"]



On 9 December 2015 at 16:09, Frankie Bagnardi <[hidden email]> wrote:
This is a common situation, but one easily solved by object literals. Reflecting on the scope is confusing and would hurt tooling (it's essentially eval).

```js
var mapping = {Polygon: Polygon};
var meshClass = mapping[ajaxData.className];
```




On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[hidden email]> wrote:
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Indirect references to variables

Robin Cafolla
In reply to this post by John Gardner
You're probably better off building some sort of class map into your application to handle this.

Either

A) You have all your classes loaded in one scope, you can have a map of strings to those classes which a method can retrieve and instantiate. Drawback is that your method (and the map) needs to also be defined in the same scope.

or

B) You don't have all classes in scope and are loading them dynamically (with something like requirejs), in which case your function needs a class-map of class names to paths, which your loader can pull in for you and asynchronously create. I tend towards using a service manager pattern to do this in applications where I have a requirement.

In the second instance you could introduce a compile step to create your class map. Very much dependent on your workflow. Regardless of how you're loading your classes or how you're scoping your code, some sort of class map is the solution.

The only case I can think of where loading by string really becomes an issue is with ES6 modules, which AFAIK, being static would need to all be loaded at the top of the module where you're de-serializing your classes.

When ES6 modules start landing in browsers I'll be tending even more strongly towards the service manager pattern: One known place to resolve instances and factories for classes.

Regards,

Robin Cafolla

On 9 December 2015 at 08:46, <[hidden email]> wrote:
Send es-discuss mailing list submissions to
        [hidden email]

To subscribe or unsubscribe via the World Wide Web, visit
        https://mail.mozilla.org/listinfo/es-discuss
or, via email, send a message with subject or body 'help' to
        [hidden email]

You can reach the person managing the list at
        [hidden email]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of es-discuss digest..."

Today's Topics:

   1. Re: Indirect references to variables (Jordan Harband)
   2. Re: Indirect references to variables (John Gardner)


---------- Forwarded message ----------
From: Jordan Harband <[hidden email]>
To: John Gardner <[hidden email]>
Cc: es-discuss <[hidden email]>
Date: Tue, 8 Dec 2015 22:39:51 -0800
Subject: Re: Indirect references to variables
Can you not put each class in its own module, and simply require, by name, the one you want?

On Tue, Dec 8, 2015 at 10:19 PM, John Gardner <[hidden email]> wrote:

Only at top-level. This issue actually surfaced when I realised I had no way to indirectly access classes by name... and for some reason, neither the global object nor the eval hack were returning anything. It worked fine for simple variables, so I wondered if that was an intentional side-effect of classes in ECMAScript.

(Of course, if not, it may actually be an issue with V8's implementation...)

On 09/12/2015 5:05 PM, "Bradley Meck" <[hidden email]> wrote:
Are you putting hundreds of classes into a single scope?

On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <[hidden email]> wrote:
Trouble is, if one has literally hundreds of classes or functions that need to be matched, they'd rather not pool them all into one massive object literal for the sake of easier mapping. DRY principle fully relevant.

Also, yes, while it would be a pain for static type analysis, it wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, whereas the indirect references would only point to modifiers only:

    var className = \"doSomethingSinister(/etc/passwd/);"

That line would literally be looking for a property in the current scope that'd be named this:

    global["doSomethingSinister(/etc/passwd/);"]
    window["doSomethingSinister(/etc/passwd/);"]



On 9 December 2015 at 16:09, Frankie Bagnardi <[hidden email]> wrote:
This is a common situation, but one easily solved by object literals. Reflecting on the scope is confusing and would hurt tooling (it's essentially eval).

```js
var mapping = {Polygon: Polygon};
var meshClass = mapping[ajaxData.className];
```




On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[hidden email]> wrote:
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




---------- Forwarded message ----------
From: John Gardner <[hidden email]>
To: Jordan Harband <[hidden email]>
Cc: es-discuss <[hidden email]>
Date: Wed, 9 Dec 2015 17:46:26 +1100
Subject: Re: Indirect references to variables

Never mind. This is beginning to south like too much of a damn edge case for it to be of language-wide relevance.

Pretend this discussion never happened.

On 09/12/2015 5:40 PM, "Jordan Harband" <[hidden email]> wrote:
Can you not put each class in its own module, and simply require, by name, the one you want?

On Tue, Dec 8, 2015 at 10:19 PM, John Gardner <[hidden email]> wrote:

Only at top-level. This issue actually surfaced when I realised I had no way to indirectly access classes by name... and for some reason, neither the global object nor the eval hack were returning anything. It worked fine for simple variables, so I wondered if that was an intentional side-effect of classes in ECMAScript.

(Of course, if not, it may actually be an issue with V8's implementation...)

On 09/12/2015 5:05 PM, "Bradley Meck" <[hidden email]> wrote:
Are you putting hundreds of classes into a single scope?

On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <[hidden email]> wrote:
Trouble is, if one has literally hundreds of classes or functions that need to be matched, they'd rather not pool them all into one massive object literal for the sake of easier mapping. DRY principle fully relevant.

Also, yes, while it would be a pain for static type analysis, it wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, whereas the indirect references would only point to modifiers only:

    var className = \"doSomethingSinister(/etc/passwd/);"

That line would literally be looking for a property in the current scope that'd be named this:

    global["doSomethingSinister(/etc/passwd/);"]
    window["doSomethingSinister(/etc/passwd/);"]



On 9 December 2015 at 16:09, Frankie Bagnardi <[hidden email]> wrote:
This is a common situation, but one easily solved by object literals. Reflecting on the scope is confusing and would hurt tooling (it's essentially eval).

```js
var mapping = {Polygon: Polygon};
var meshClass = mapping[ajaxData.className];
```




On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[hidden email]> wrote:
ECMAScript currently offers no clean way to "dereference" a variable in the current scope. For instance, assume an author wishes to obtain a reference to a class using a variable that holds its name:

    class Paintbrush{  }

    let className = "Paintbrush";
    
    // Would only work in browsers, not NodeJS
    console.log( window[className] );

    // Doesn't even work in NodeJS
    console.log( global[className] || this[className] );

A hacky workaround is to create an anonymous function that simply returns a reference to the named variable:

    function dereference(name){
        return new Function([], "return " + name)();
    }
    dereference("Paintbrush") === Paintbrush; // true

This isn't an elegant solution, nor a preferable one. Another approach might be to leverage `eval`, which opens up the obvious issues of performance and security.

Having a way of indirectly referencing another variable would fix this:

    class Paintbrush{  }

    let className       = "Paintbrush";

    let classReference  = \className;
    console.log(classReference === Paintbrush); // true

Sticking a backslash before a bareword identifier creates a reference to an object whose name matches the identifier's string value. If no such object exists in the current scope, it simply returns `undefined`.

I can't see this being used in everyday programs, but it would facilitate Ajax programming considerably, where classes or functions can only be specified by name:

    {"className":"Polygon", "vertices": [[0,0]...] }

    let meshClass = \ajaxData.className;
    if(meshClass instanceof Mesh){
        new meshClass(ajaxData.vertices);
    }




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss