Help with Javascript: naming variables using other variables

S

sagejoshua

Help!

Is there a way to declare a variable name using other variables in
Javascript? In PHP, it's done with something like:

<?php

$var1 = "foo";
${$var1.bar} = "great!";

print $foobar;

// Outputs "great!"

?>

Is there a similar method in Javascript?

Thanks.
Josh
 
J

Jonathan N. Little

sagejoshua said:
Help!

Is there a way to declare a variable name using other variables in
Javascript? In PHP, it's done with something like:

<?php

$var1 = "foo";
${$var1.bar} = "great!";

print $foobar;

// Outputs "great!"

?>

Is there a similar method in Javascript?

Thanks.
Josh

var foo="Value of Foo";
var bar="foo";
alert( "foo=" + foo + "\n evail of bar=" + eval(bar) );
 
S

sagejoshua

var foo="Value of Foo";
var bar="foo";
alert( "foo=" + foo + "\n evail of bar=" + eval(bar) );

Awesome. Works like a charm. Thanks for the quick help.

Josh
 
M

Michael Winter

On 06/11/2005 16:54, Jonathan N. Little wrote:

[snip]
var foo="Value of Foo";
var bar="foo";
alert( "foo=" + foo + "\n evail of bar=" + eval(bar) );

The eval function is evil. It's use is rarely ever necessary.

ECMAScript provides bracket notation as an alternative to dot notation
property accessors. This form allows any expression, including function
calls and variables, which will be evaluated and type-converted to a
string. The result will then be used as the property name.

Global variables, such as foo and bar, above, are members of the global
object:

var global = this; /* The window identifier also refers
* to the global object in browsers.
*/

alert(global[bar]); /* 'Value of Foo' */

See Bracket Notation[1] in the c.l.javascript FAQ notes.

Mike


[1] <http://www.jibbering.com/faq/faq_notes/square_brackets.html>
 
X

X l e c t r i c

sagejoshua wrote:

"Help!

Is there a way to declare a variable name using other variables in
Javascript? In PHP, it's done with something like:

<?php
$var1 = "foo";
${$var1.bar} = "great!";
print $foobar;
// Outputs "great!"
?>

Is there a similar method in Javascript?

Thanks.

Josh"

Are you sure that outputs "great!" ?

Jonathan N. Little wrote:

"var foo="Value of Foo";
var bar="foo";
alert( "foo=" + foo + "\n evail of bar=" + eval(bar) );"

There's no need for eval (or evail):

var foo = "Value of Foo";
var bar = foo;
alert("foo = " + foo + ".\n\nBecause the value of the variable bar now
equals the value of the variable foo, bar also = " + bar + ", without
the need of eval.");

Later, Art.
 
J

Jonathan N. Little

X said:
sagejoshua wrote:

"Help!

Is there a way to declare a variable name using other variables in
Javascript? In PHP, it's done with something like:

<?php
$var1 = "foo";
${$var1.bar} = "great!";
print $foobar;
// Outputs "great!"
?>

Is there a similar method in Javascript?

Thanks.

Josh"

Are you sure that outputs "great!" ?

Jonathan N. Little wrote:

"var foo="Value of Foo";
var bar="foo";
alert( "foo=" + foo + "\n evail of bar=" + eval(bar) );"

There's no need for eval (or evail):

var foo = "Value of Foo";
var bar = foo;
alert("foo = " + foo + ".\n\nBecause the value of the variable bar now
equals the value of the variable foo, bar also = " + bar + ", without
the need of eval.");

You misunderstand, OP wants a variable-variable not a copy of a variable
with a different identifier, that is a variable with another variable's
name in it.

var hither="Close by";
var yonder="In the hills!";

Michael has the far better solution to avoid 'evail'

var global = this;

var whereAmI="hither";
alert(global[whereAmI]); //displays 'Close by'

whereAmI="yonder";
alert(global[whereAmI]); //now displays 'In the hills!'
 
X

X l e c t r i c

Jonathan N. Little wrote:

"You misunderstand, OP wants a variable-variable not a copy of a
variable with a different identifier, that is a variable with another
variable's name in it.

var hither="Close by";
var yonder="In the hills!";

Michael has the far better solution to avoid 'evail'

var global = this;
var whereAmI="hither";
alert(global[whereAmI]); //displays 'Close by'
whereAmI="yonder";
alert(global[whereAmI]); //now displays 'In the hills!'

--

Take care,

Jonathan"

Actually my point was about the unnecessary use of eval.

Michael and the other experts at comp.lang.javascript have helped me
many times, cwdjr too. And even though in this case his reply was more
directly related to and appropriate for the OP's question, who is to say
what is "far better". As we don't know the context with which this bit
of code will be used.

I could easily say that this:

var hither = "Close by";
var yonder = "In the hills!";
alert(hither);
alert(yonder);

is far more efficient and practical than what you offer, as the results
will be the same with a more simplistic approach. What I can't say
though is that this is the solution in any given situation without
knowing the application.

Later, Art.
 
J

Jonathan N. Little

X said:
Actually my point was about the unnecessary use of eval.

Michael and the other experts at comp.lang.javascript have helped me
many times, cwdjr too. And even though in this case his reply was more
directly related to and appropriate for the OP's question, who is to say
what is "far better". As we don't know the context with which this bit
of code will be used.

I could easily say that this:

var hither = "Close by";
var yonder = "In the hills!";
alert(hither);
alert(yonder);

is far more efficient and practical than what you offer, as the results
will be the same with a more simplistic approach. What I can't say
though is that this is the solution in any given situation without
knowing the application.

I agree accessing variables directly is simpler and more efficient, but
the OP was looking for a JS version of a PHP's variable variable which
the above method does not address. Personally I avoid variable
variables, I find you can really get yourself into trouble and they can
be a b*tch to debug, but again it was what the OP asked.
 
X

X l e c t r i c

Jonathan N. Little wrote:

"but again it was what the OP asked."

Which in fact is the bottom line. And regardless of your opinions you
offered a solution. Which is the way it should be.

I hope you do the same when I ask for help.

Later, Art.
 
X

X l e c t r i c

sagejoshua wrote:

"<?php
$var1 = "foo";
${$var1.bar} = "great!";
print $foobar;
// Outputs "great!"
?>

Are you sure that outputs "great!" ?

Yep.

Josh"

Is $var1.bar PHP 5 dot notation ?

If so, then that explains why it doesn't work for me. The host I tried
it at is at PHP 4.3.11.

Later, Art.
 
J

Jonathan N. Little

X said:
Jonathan N. Little wrote:

"but again it was what the OP asked."

Which in fact is the bottom line. And regardless of your opinions you
offered a solution. Which is the way it should be.

I hope you do the same when I ask for help.

Later, Art.

A little confused by your response, partly your very non-standard way of
quoting previous text conflicts with quotes used in message and also
doesn't account for multiple levels of quotation...
 
L

Leif K-Brooks

X said:
Is $var1.bar PHP 5 dot notation ?

If so, then that explains why it doesn't work for me. The host I tried
it at is at PHP 4.3.11.

No, it's concatenation
<http://php.net/manual/en/language.operators.string.php> combined with
abuse of a PHP misfeature which turns missing constants into strings. It
works fine with my copy of PHP 4.3.10:

leif@debian:~$ php -v
PHP 4.3.10-15 (cli) (built: May 9 2005 08:54:56)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
leif@debian:~/ecritters/web/html$ php
<?php
$var1 = "foo";
${$var1.bar} = "great!";
print $foobar;
// Outputs "great!"
?>
great!leif@debian:~$
 
X

X l e c t r i c

Leif K-Brooks wrote:

"No, it's concatenation

<http://php.net/manual/en/language.operators.string.php> combined with
abuse of a PHP misfeature which turns missing constants into strings. It
works fine with my copy of PHP 4.3.10:

leif@debian:~$ php -v
PHP 4.3.10-15 (cli) (built: May 9 2005 08:54:56) Copyright (c) 1997-2004
The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
leif@debian:~/ecritters/web/html$ php
<?php
$var1 = "foo";
${$var1.bar} = "great!";
print $foobar;
// Outputs "great!"
?>
great!leif@debian:~$""

I obvoiusly did something wrong. I'll go try it again.

Thanks, Art.
 
M

Michael Winter

sagejoshua wrote:
[snip]
<?php
$var1 = "foo";
${$var1.bar} = "great!";
print $foobar;
// Outputs "great!"
?>
[snip]

Are you sure that outputs "great!" ?

[snip]

To elaborate on what Leif wrote, the variable variable constructed above
is made possible through string concatenation, similar to

var variable = 'foo';

this[variable + 'bar'] = 'Great!'; /* foobar = 'Great!'; */

in ECMAScript. However, rather than using a string literal, the OP has
written in bar what would normally considered a constant. Indeed, if
STRICT notices are enabled in PHP, this will be reported in the error log.

It would be better written as:

<?php
$variable = 'foo';
${$variable . 'bar'} = 'Great!';
print $foobar; /* Great! */
?>

Mike
 
S

sagejoshua

To elaborate on what Leif wrote, the variable variable constructed above
is made possible through string concatenation, similar to

var variable = 'foo';

this[variable + 'bar'] = 'Great!'; /* foobar = 'Great!'; */

Ah, it all starts to make sense now. You can refer to any variable
using the "global array" this[whatever], and whatever is in the
brackets will be parsed. Very nice tool. My question is, what's so
evil about eval()?
in ECMAScript. However, rather than using a string literal, the OP has
written in bar what would normally considered a constant. Indeed, if
STRICT notices are enabled in PHP, this will be reported in the error log.

It would be better written as:

<?php
$variable = 'foo';
${$variable . 'bar'} = 'Great!';
print $foobar; /* Great! */
?>

Yeah, you're right. I was just being sloppy.


Thanks for all the help.
Josh
 
M

Michael Winter

On Mon, 07 Nov 2005 13:53:53 GMT, Michael Winter
[snip]
var variable = 'foo';

this[variable + 'bar'] = 'Great!'; /* foobar = 'Great!'; */

Ah, it all starts to make sense now. You can refer to any variable
using the "global array" this[whatever], and whatever is in the
brackets will be parsed.

That's a rather simplistic summation, so I'll clarify.

This'll take a while...

/All/ variables and functions are properties of an object. Variables and
functions declared in 'global scope' are properties of the global
object. Function-local variables and inner functions are properties of
the Variable object of their containing function (I'll come back to that
later).

function outer() {
var local;

function inner() {
}

/* Both local and inner are properties
* of the Variable object of outer.
*/
}

Finally, there are the properties and methods of built-in, host, and
user-defined objects.

Bracket notation, like dot notation, is a form of property accessor. As
an example,

myObject.myProperty

and

myObject['myProperty']

are equivalent. Given an object reference, either one could be used to
access a property of that object.

There are two differences between these features.

1. The right-hand operand (the property name) in a dot notation
property accessor is a fixed value. However, bracket
notation allows expressions including, but not limited to,
string concatenation, function calls, and variables.

var myObject = {},
myPropertyName = 'myProperty';

myObject.myPropertyName /* myObject.myPropertyName */
myObject[myPropertyName] /* myObject.myProperty */

2. With dot notation, the property name must match the
Identifier production. That is, it must start with a letter,
dollar ($), or underscore (_), and may be followed by any of
those characters or digits[1]. The property name used with
bracket notation can involve any characters, including
white space and those normally reserved as operators.

var myObject = {};

myObject.two words /* Syntax error */
myObject['two words'] /* OK */
myObject.nuts+bolts /* Addition - not intended */
myObject['nuts+bolts'] /* OK */


Now, looking back to the example that I posted previously (quoted at the
start of this post), in 'global scope' the this operator is a reference
to the global object (it differs in other contexts). So, rather than
referring to 'any variable' (your words), it could refer only to global
variables with code executing in 'global scope'.

If the this operator is replaced with some other object reference - such
as window or the variable named global I defined in a previous post, or
a different object entirely - the object properties available, as well
as the scopes they can be referenced from, will obviously change.


I wrote earlier that I'd re-address the Variable object: the object used
by functions to hold local variables. Unfortunately, this object is only
a specification mechanism. Implementations may use such an object to
hold local variables (they don't have to), but scripts cannot access it.
This means that you cannot directly use bracket notation to construct
variable names for locals. However, you could create your own object
with which to accomplish the same thing:

function myFunction() {
var locals = { myLocal1 : 'a value',
myLocal2 : 'a second value',
myLocal3 : 'a third' };

for(var i = 1, i <= 3; ++i) {
document.write(i + ': '
+ locals['myLocal' + i]
+ '<br>\n');
}
}
myFunction(); /* Outputs: 1: a value
* 2: a second value
* 3: a third
*/
My question is, what's so evil about eval()?

Various things. This isn't exhaustive.

- Code evaluated by eval is often harder to debug and maintain,
not least due to the loss of formatting and the delay in
evaluation.
- Code execution is slower as the code will have to be
re-evaluated, and a new execution context derived from the
calling context, on each eval call. The code will also be
evaluated as a Program production - the root grammar
production.
- The use of eval isn't often understood, and there are far too
many examples of this on the Web. For instance, it's been
used to type-convert strings into numbers, despite the fact
that it's wholly inappropriate. Unfortunately, this can often
lead others into thinking that eval is some magical catch-all
feature that will solve whatever problem the author is trying
to overcome at the time.

Defining appropriate usage is rather difficult as it's rare. For the
majority of authors, 'never' would suffice. For others? Well, if they're
reading this post they have Usenet access, so they can go to
c.l.javascript and ask if there's a better alternative. :)

Mike


[1] That is a typified description, and probably all one should
concern oneself with. However, there are other characters
that are permitted. See 7.6 - Identifiers in ECMA-262. I've
never investigated how well browsers conform with that
section.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top