|
Posted by Michael Winter on 10/24/53 11:31
On 07/11/2005 16:10, sagejoshua wrote:
> On Mon, 07 Nov 2005 13:53:53 GMT, Michael Winter
> <m.winter@blueyonder.co.uk> wrote:
[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.
--
Michael Winter
Prefix subject with [News] before replying by e-mail.
[Back to original message]
|