Re: changing text
Tjerk Wolterink wrote:[color=blue]
> Richard Cornford wrote:[/color]
<snip>[color=blue][color=green]
>> ... . Your code used a global variable as a
>> loop counter, ...[/color][/color]
<snip>[color=blue]
> did i do that?
>
> the code:
>
> function changeText() {
> var element=documen t.getElemenyByI d("myText");
> var children=elemen t.childNodes;
> for(i=0;i<child ren.length;i++) {
> element.removeC hild(children.i tem(i));
> }
> element.appendC hild(document.c reateTextNode(" new Text"));
> }
>
> is see nothing wrong with it. i is in the scope
> of changetext,[/color]
That depends a lot on how you think about the scope of - changetext -.
At the point of first executing - changetext - there are no object in
the system with a property named "i". The function object that is
referred to by the property of the global object with the name
'changetext' has an internal [[Scope]] property that points to the scope
chain in which it was created. That function object was created in the
global scope so that internal [[Scope]] property points to a scope chain
containing only the global object.
When - changetext - is executed its execution context has a scope chain
consisting of a Variable/Activation object followed by the objects in
the scope chain referred to by the function object's internal [[Scope]]
property. So that is a scope chain that is two objects deep, the
Activation/Variable object followed by the global object.
The execution context's Variable/Activation object has named properties
for each formal parameter, inner function declaration and each function
local variable (as declared with the - var - keyword) within the
function. In this case -changetext - has no formal parameters and no
inner function declarations so the Variable/Activation object has three
named properties. One for each of the declared function local
variables; - element - and - children -, and one for the - arguments -
object that is created for each execution context.
The identifier - i - is resolved against the execution context's scope
chain (as per ECMA 262 3rd edition; Section 10.1.4), but the first time
it is referred to (as -> i = 0) there is no object on that scope chain
with a property named "i" so the result is a Reference type with a null
base object and the property name "i". An assignment to such a Reference
substitutes the global object for the null base object (ECMA262 3rd
edition; Section 8.7.2) and as the global object has no property named
"i", such a property is created and the value (zero) assigned to it.
And so - i - is created as a global variable by the act of assigning a
value to an identifier that cannot be resolved against the scope chain.
All subsequent references to - i - are resolved as a reference to that
property of the global object.
[color=blue]
> ok i should have put a var before it like this:
>
> for(var i=0;i<children. length;i++) {
> element.removeC hild(children.i tem(i));
> }[/color]
Yes you should. Using the - var - keyword would result in a proerty of
the execution context's Varaible/Activation object being created wit the
name "i" and so the identifier - i - would resolve as a referrence to
the "i" proeprty of that object, which only appears on the scope chain
of the current exectuion context and the [[Scope]] proeprties of
fucntion objects created within that execution context (or nested within
the execution contexts of those inner fucntions). I.E. With - var - it
is a fucntion local variable, and without it - i - becomes a global
varaible.
Javascript's lexical scopeing may not be as fine-grained as Java's block
scopeing but that is no reason disregard the scope of variables. Indeed,
the language's native support for closures makes understanding variable
scope potentially very valuable and exploitable.
[color=blue]
> but that doesnt change the meaning of the loop.[/color]
<snip>
The meaning of things was never the issue with global variables, it is
the interactions between things that are effected by the scope of the
variables they reference.
Richard.
Tjerk Wolterink wrote:[color=blue]
> Richard Cornford wrote:[/color]
<snip>[color=blue][color=green]
>> ... . Your code used a global variable as a
>> loop counter, ...[/color][/color]
<snip>[color=blue]
> did i do that?
>
> the code:
>
> function changeText() {
> var element=documen t.getElemenyByI d("myText");
> var children=elemen t.childNodes;
> for(i=0;i<child ren.length;i++) {
> element.removeC hild(children.i tem(i));
> }
> element.appendC hild(document.c reateTextNode(" new Text"));
> }
>
> is see nothing wrong with it. i is in the scope
> of changetext,[/color]
That depends a lot on how you think about the scope of - changetext -.
At the point of first executing - changetext - there are no object in
the system with a property named "i". The function object that is
referred to by the property of the global object with the name
'changetext' has an internal [[Scope]] property that points to the scope
chain in which it was created. That function object was created in the
global scope so that internal [[Scope]] property points to a scope chain
containing only the global object.
When - changetext - is executed its execution context has a scope chain
consisting of a Variable/Activation object followed by the objects in
the scope chain referred to by the function object's internal [[Scope]]
property. So that is a scope chain that is two objects deep, the
Activation/Variable object followed by the global object.
The execution context's Variable/Activation object has named properties
for each formal parameter, inner function declaration and each function
local variable (as declared with the - var - keyword) within the
function. In this case -changetext - has no formal parameters and no
inner function declarations so the Variable/Activation object has three
named properties. One for each of the declared function local
variables; - element - and - children -, and one for the - arguments -
object that is created for each execution context.
The identifier - i - is resolved against the execution context's scope
chain (as per ECMA 262 3rd edition; Section 10.1.4), but the first time
it is referred to (as -> i = 0) there is no object on that scope chain
with a property named "i" so the result is a Reference type with a null
base object and the property name "i". An assignment to such a Reference
substitutes the global object for the null base object (ECMA262 3rd
edition; Section 8.7.2) and as the global object has no property named
"i", such a property is created and the value (zero) assigned to it.
And so - i - is created as a global variable by the act of assigning a
value to an identifier that cannot be resolved against the scope chain.
All subsequent references to - i - are resolved as a reference to that
property of the global object.
[color=blue]
> ok i should have put a var before it like this:
>
> for(var i=0;i<children. length;i++) {
> element.removeC hild(children.i tem(i));
> }[/color]
Yes you should. Using the - var - keyword would result in a proerty of
the execution context's Varaible/Activation object being created wit the
name "i" and so the identifier - i - would resolve as a referrence to
the "i" proeprty of that object, which only appears on the scope chain
of the current exectuion context and the [[Scope]] proeprties of
fucntion objects created within that execution context (or nested within
the execution contexts of those inner fucntions). I.E. With - var - it
is a fucntion local variable, and without it - i - becomes a global
varaible.
Javascript's lexical scopeing may not be as fine-grained as Java's block
scopeing but that is no reason disregard the scope of variables. Indeed,
the language's native support for closures makes understanding variable
scope potentially very valuable and exploitable.
[color=blue]
> but that doesnt change the meaning of the loop.[/color]
<snip>
The meaning of things was never the issue with global variables, it is
the interactions between things that are effected by the scope of the
variables they reference.
Richard.
Comment