Using setInterval inside an object

D

Daniel

Lasse Reichstein Nielsen said:
That is a step on the way to understanding, making the concepts fit
inside ones head. However, words that make sense in your mind, often
ends up making little or no sense when taken out of that context. :)

Tell me about it! Hehe =)
Or, as somebody once said: You haven't really understood something
before you can explain it clearly. (He was right!)

Come to think of it, that's pretty much how I know I've really understood
something, which is probably why I keep babbling and babbling on about this,
because I can't say that I'd be able to teach someone else this and know I
was telling the truth :) Also, I'm pretty sure I could use these skills now
without causing errors, but I guess the quest right now really is that I
want to be able to explain it clearly. So right on!
I think you are putting the parentheses in the wrong places. The code was

var anObject = function(){...} ();

I think you are reading it as

(var anObject = function(){...}) ();

i.e., assign the function value to the anObject variable first, then
call it. This is syntacitcally illegal, since the "var" keyword makes
it a declaration, and declarations have no value. The correct way of
reading it, however, is

var anObject = (function(){...} ());

GREAT way to put it! Actually, I think of the parentheses like this:

var anObject = (function(){...})();

with (function(){...}) being evaluated first, then the return value of that
being evaluated by (); then the return value of that being assigned to
anObject.

But that's not entirely true, because at the point of assigning anObject a
value, which, as I understand, is what is happening here, I don't see any
evaluation being made just yet, at that point I see it as you put it, that
is:

var anObject = (function(){...}();)

in the sense that at this particular instant in time, anObject holds a
reference to all definitions inside these parentheses, and these definitions
will stay "untouched" or "unexecuted" or "unevaluated" or "unprocessed" ;)
until anObject is called in another context. So when I say above that,
"...the return value of that being assigned to anObject", that would require
its invocation context to be simply:

anObject();

However, the way we use it, as an object construct -

var myInstance = new anObject();

- I see "...the return value of that being assigned to anObject", but
"anObject" in this context being nothing more than the courier of the
reference it holds inside, i.e. returns to an expression, i.e. assigns to
the given variable. In this context, to properly explain this with
parenthesis, I'd probably write a combination of the former two:

((function(){...})();)

- and lose the "var anObject" assignment part because that would be implied,
not as a variable holding the evaluated contents of the parentheses above,
but the yet unevaluated definition contents - the actual evaluation and
solution of the parentheses take place at that particular time and not
before.

That's pretty much how I understand that.
There is no "anObject" function. If you bound the function first, say using
(anObject = function(){...}) ();
(without the "var" so it is legal), then anObject would be a function, but
the "()" would call that function, not the value returned by it. The returned
value is actually lost.

I'm glad you write this, because that's actually exactly what I mean =) (See
why I say you're better at English than I am? ;)
yes?

The execution goes like this:

1 : create anonymous function (a "function expression"):
function() { document.write ... return constructor}
2 : call the function from 1
2.1 : execute document.write("1")
2.2 : create an anonymous function (a "function expression"):
function() {document.write(" 2");}

With you so far.
2.3 : assign the result of 2.2 to the new global variable "constructor".

Global? I thought it'd be a private member of oneOff?
2.4 : return the value of the global variable "constructor". This is the
result of 2.
3 : assign the result of 2 to the local variable "oneOff".
4 : use the value of the variable "oneOff" as a constructor with
no arguments (new ...()). That is, create a new object and
call the function with "this" pointing to the new object.
4.1 : execute document.write(" 2")

This is executed as a result of the instantiation of the constructor object,
right? Not Mr. One-Off?
4.2 : since nothing is returned, the result of the "new"-expression (and
the result of 4) is the new object.
5 : assign the result of 4 to the variable "test".

I'm with you all the way (except for the global constructor variable), and
thank you for putting it like this, because the sequence was a bit messy in
my head, seeing it like this makes it perfectly clear :)

I would just call it "constructor function"
I would just called it "object", "instance of myconstructor" or
"constructed object". Shorter is (sometimes) better :)
<snip>

Oh yes =)
That is much closer to Javascript than most languages then. Javascript
is a prototype based (as oppesed to class based) object oriented language.

That's what I thought, since they're both ECMA-based, but when I see "class"
being used, I suddenly start wondering... I do that a lot...
In that case, I actually think you *do* get it (apart from a minor
detail about how function application and assignment associates),
Daniel, but for your own sake, work on your ability to precisely
explain what you mean!

Woohoooo!!! =)
You'll go far with that attitude :)

You just wait and see, one day you guys will be asking ME for help! *L* ;)

Thanks mate!

Daniel


PS: I think this thread is getting really good reading for newbies trying to
understand stuff like this, don't you guys? Your expertise and my daftness
is a winning cocktail! We oughta write some books! ;)
 
L

Lasse Reichstein Nielsen

Daniel said:
GREAT way to put it! Actually, I think of the parentheses like this:

var anObject = (function(){...})();

with (function(){...}) being evaluated first, then the return value of that
being evaluated by (); then the return value of that being assigned to
anObject.

Here you are using confuzing terminology (saying "return value" twice
even though there is only one function call). I'll try to be very
precise:

"function (){...}" is a function *expression* (a sequence of
characters that match a production of the grammar called "function
expression"). It is an expression (rather than, e.g., a statement), so
it can be evaluated to a value.

That value is a function *value* (you say "return value", but there is
nothing being returned yet, the body of the function is not evaluated
at this point). Functions in Javascript are objects which have an
internal method called "[[Call]]".

"(function(){...})()" is again an expression, in this case a function
application. It consists of two parts, the *expression* before the
parentheses, which should (if the program is correct) evaluate to a
function *value*, and the argument expressions og which there are zero
in this case.

To evaluate a function application, first evaluate the expression in
the function-position. In this case it is a function expression, so
it directly evaluates to an (anonymous) function value. Then evaluate
the arguments, in this case it is trivial. Finally, call the function with
the arguments. At this point, the body of the function is evaluated.
The reteurn value of *that* is the value of the application expression.

"var anObject = function(){...}();" is not an expression, it is a statement.
More precisely, it is a "variable declaration and initalization" statement.
The Javascript interpreter already noticed that "anObject" was declared
as a local variable, it checks that before executing anything, so the scope
of the variable can precede its declaration.

To find the effect of a statement, it is executed (not evaluated, as
it doesn't have to have a value). To execute an assignment (what an
initialization statement really is), you first evaluate the right-hand
side expression. In this case, it is the return value of calling the
anonymous function. Then, and only then, is the "anObject" variable
bound to that value. Until this, it has been undefined.

That value, the return value of the call to the anonymous function
(which we have no reference to otherwise[1], so it will never be
called again) just happens to be a function itself, a completely
different function.
But that's not entirely true, because at the point of assigning anObject a
value, which, as I understand, is what is happening here, I don't see any
evaluation being made just yet, at that point I see it as you put it, that
is:

var anObject = (function(){...}();)

in the sense that at this particular instant in time, anObject holds a
reference to all definitions inside these parentheses, and these definitions
will stay "untouched" or "unexecuted" or "unevaluated" or "unprocessed" ;)
until anObject is called in another context.

Not so. The parentheses (they are curved, not squiggly) are only grouping.
They don't delay the execution. Javascript is a strict language, so you don't
pass around unevaluated code just like that.
I'm glad you write this, because that's actually exactly what I mean =) (See
why I say you're better at English than I am? ;)

Years of practice writing academic English will do that to you. I can
talk for hours about closures, but I have little to no knowledge of
the names of kitchen utensils :)
Global? I thought it'd be a private member of oneOff?

The constructor variable has not been declared local by a "var
constructor" declaration. Therefore it defaults to being global.
This is executed as a result of the instantiation of the constructor object,
right? Not Mr. One-Off?

The value of the variable "oneOff" is a function. That function's body
contains 'document.write(" 2")'. When writing "new oneOff()" you use
that function as a constructor, but that includes calling it as a function.
The "document.write" is executed as part of the expression "new oneOff()".

That's what I thought, since they're both ECMA-based, but when I see "class"
being used, I suddenly start wondering... I do that a lot...

You can emulate classes in Javascript, and people sometimes refer to
elements created using the built in constructors (e.g., Array) as
"instances of the class Array". It is, however, people used to class
based languages that are trying to hammer in a screw.

Needless detail on how objects are created:

Objects are, obviously, an important datatype for Javascript. As I
said earlier, functions are objects with some extra functionality, and
so are Regular Expressions and a lot of other utility objects.

All objects have a property called "constructor". It refers to the
function that was (or could have been) used as a constructor to create
the object. If you write "var x={};" then "x" refers to a new,
(almost) empty object. The constructor for it is the one called
"Object". The constructor of an array is "Array", and so on.

Each function can be used as a constructor and therefore has a
property (remember, they are objects too) called "prototype". When you
look for a property of an object, it first checks if the object has
had that property assigned to it. If not, it checks if it is a
property of its prototype, and if not, it continues down the prototype
chain (I haven't checked where it ends, but probably at Object.prototype).

Quiz: What does the following do?
---
var x = new Object();
Object.prototype.foo = 42;
alert(x.foo);
---

When you call a function as a method of an object, the "this" keyword
will refer to that object. That is:
---
var x = new Object();
x.foo = function () {return this;};
alert(x == x.foo());
---
will alert "true".
It is the "." notation (or the equivalent []-notation) that marks a
function call as a method invocation. If you changed the above to:
---
var x = new Object();
x.foo = function () {return this;};
var bar = x.foo;
alert(x == bar());
---
it alerts "false", even though "x.foo" and "bar" both refer to the
exact same function object. It is the way the function is called that
sets the "this" keyword's value. When you call a function directly,
and not as part of an object, then the "this" keyword refers to the
global object, where the global variables live.


Since there are no classes in Javascript, the term "constructor" might
also be a little misleading. As I said, any function can be used as a
constructor. What happens when you write
new foo(42);
is that you call the function "foo" with the argument "42". However,
where a normal function call of that kind would have set the "this"
reference to the global object, and a method invocation would set
"this" to the object of the method, the "new" makes sure that the
"this" keyword refers to an entirely new object. If the foo function
doesn't return something (or if it returns something that is not an
object), that new object is the value of the entire expression. If
it returns another object, they object will be the value of the "new"
expression.

---
function foo(x) {
this.n=x;
}

foo(37); /* sets this.n = 37 with this == global object */

var o1 = new Object();
o1.bar = foo;
o1.bar(42); /* sets this.n = 42 with this == o1 */

var o2 = new foo(87); /* sets this.n = 87 with this == new object == o2 */

alert(n +","+ o1.n +","+ o2.n); /* alerts "37,42,87" */
 
R

Richard Cornford

That said, I did mean that the object was changed somehow,
but I see your point that everything stays the same (except
from variable values, ofcourse).

But still, I don't see the anonymity of the "original" MyObject function
being the result of function expression, since it isn't anonymous before
after it's been called. Up until that point it does exist as MyObject, as a
definition yes, but it still has a reference... To me, a truly anonymous
function expression would be something like

myArray.sort(function(a,b){ return subCmp(a[label],b[label]); });

...And then you write this:
var anObject = funciton(){
return new Array();
}();
^- It is the pair of brackets after the function
expression that execute it (in-line and once only).
... "object doesn't support this action", ...
<snip>

Ops, that's my fault. If you look closely at the way I have spelled
function you will notice that the t and the i have been transposed. One
of the hazards of touch typing into a word processor instead of a
syntax-highlighting text editor. Though I am surprised that I did not
notice Word complaining about the spelling, but there is a tendency to
ignore highlighted spelling mistakes when entering code in Word. Sorry
if that was confusion, correct the spelling an it will work as
advertised.

... . I can see that the "hijacking" term is bad because it indicates
that it's the same reference that's been "unplugged" from "oneOff"
and "plugged into" the "constructor" function, which probably isn't
the case. But "oneOff" used to hold a reference to a function definition,
and now, after evaluating that definition, it holds a reference to
something else... Hm...
<snip>

My reason for stressing that the assignment operation had a left hand
side (var MyObject) and a right hand side (all the rest of the
statement) was to try and explain how MyObject was only ever assigned
the end result of the right hand side. There is not "hijacking" because
the only value that is ever associated with the MyObject variable is a
reference to a function object that was originally created as the inner
function "constructor" within the execution context of the one-off
function execution.

You seem to be seeing too much happening at once and Lasse is right,
parenthesising the original statement should make the real sequence of
events clearer.

ECMA script assigns precedence to various operations, so while:-

alert( 1 + 2 * 4 );

- could alert 12 or 9 in practice it always alerts 9 because the - * -
operator has higher precedence than the - + - operator. The order of
evaluation of an expression can be altered by using parentheses to
bracket the addition operation - alert( (1 + 2) * 4 ); - which alerts 12
because the addition Is forced to happen before the multiplication
instead of after. Because ECMA Script defines precedence for operations
the original alert statement can be bracketed as - alert( 1 + (2 *
4) ); - and still produce the original result 9. That arrangement of
brackets can be considered the "natural" parenthesising of the
expression. So:-

var MyObject = function(){ . . . }();

- (as a shorthand form of the original example) can "naturally" be
parenthesised as:-

var MyObject = ( ( function(){ . . . } )() );
^- notice that the
statement terminating semicolon must be
outside of the parentheses for this to
remain legal JavaScript syntax. In the
same way as the - var - cannot be placed
within parentheses.

For the interpreter to discover what value to assign to the MyObject
variable it must evaluate the whole of the expression on the right hand
side of the - = -, the contents of the outer set of brackets. The
evaluation of the contents of the outer set of brackets must start with
the contents of the innermost brackets, which contain - function(){ . .
.. } -, a truly anonymous function expression. Anonymous because once the
function object has been created the _only_ reference to it is the
result of the evaluation of the innermost bracketed expression. If we
refer to the result of the evaluation of the innermost set of brackets
as - temporaryInternalFunctionReference - and replace those brackets
with that we get:-

var MyObject = ( temporaryInternalFunctionReference() );

The next stage in the process is the evaluation of the contents of the
remaining set of brackets. That step is the execution of the function
object referred to by the result of the evaluation of the contents of
the inner set of brackets. That function is the outer function so the
result of executing it is its return value, the inner function
"constructor" that may later be used as an object constructor.

Having fully resolved the right hand side of the assignment operator,
and acquired the reference to the inner "constructor" function as the
result, The last part of the process is to assign that value to the
MyObject variable.

Up until that final assignment of the reference to the inner
"constructor" function object MyObject has not referred to anything. It
has also never known anything about what is going on to the right of
the - = - operator.
From that point on MyObject can be used with the - new - keyword to
construct objects because it refers to a function object, and because
that function object has been created with code that is appropriate to
an object constructor (and has had additional methods assigned to its
prototype) using - new MyObject("anyString"); - is a reasonable thing to
do and will create a usable object.

... I.e. it starts reading, and says

1) var : "Aha, you want a variable, what should we call it?"
2) objectInstance : "Great name!"
3) = : "Okay, sure, let's assign it a value right away"
4) new : "Oh, so you want an instance of an object, do you? Let's
see what that object could be."
5) MyObject(); : "Well, I'll just evaluate that and get back to
you" [evaluating, finding the one-off function, evaluating it, doing
parser stuff, returning the constructor](*) "Okay, I have the guidelines
now, let's make that instance" [making an instance of the constructor,
then assigning it to "objectInstance"]

At the point of executing:-

var objectInstance = MyObject();

- the MyObject variable already contains a reference to the inner
function that was defined with the name "constructor". The one-off
function has already been executed and done its work, At this point The
one-off function has no accessible references and will never be executed
again.

... I'm not used to classes, since in Actionscript everything
is essentially an object (or a prototype). I just saw it in your
code, and thought, well... Don't know what I thought, really

As Actionscript is an ECMA implementation everything that we have been
discussing to date will apply equally to Actionscript.

Classes are a concept that is explicit in other object orientated
languages like Java but there is nothing within ECMA Script that
explicitly represents a class.

For comparison, if my original MyObject Class was defined in Java it
would look something like:-

public class MyObject{
private static int counter = 0;
private static void incrementCounter(){
return MyObject.counter++;
}
public String id;
private MyObject self;
private int index;
/* class constructor. */
public MyObject(String id){
this.id = id;
this.self = this; //not needed in Java!
this.index = MyObject.incrementCounter();
};
public int getIndex(){
return this.index;
}
public static int getNoOfInsts(){
return MyObject.counter;
}
public String getId(){
return this.id;
}
}

- As you can see the class is a very concrete structure. It is also a
very final structure, once defined and compiled this class structure
specifies an exact template with which all instances of the Java
MyObject class will be drawn.

The template for an ECMA Script object is much more loosely defined, and
it is also mutable (though you wouldn't often want to do that). If my
original class was defined in the more traditional JavaScript way, as a
separate constructor function and as properties of that function and its
prototype object (the private members must now be public members as
there are no closures to contain them), the results would look like:-

function MyObject(){
this.id = id;
this.self = this; //pointless in an object with no inner functions
this.index = MyObject.incrementCounter();
}
MyObject.prototype.getIndex = function(){
return this.index;
}
MyObject.counter = 0;
MyObject.incrementCounter = function(){
MyObject.counter++;
}
MyObject.getNoOfInsts = function(){
return counter;
}
MyObject.prototype.getId = function(){
return this.id;
}

It is not a single structure but a sequence of statements. Its whole
does still act as a template with which all instances of MyObject are
created. That makes this combined definition of the MyObject
constructor, its properties and the properties of its prototype
analogous to the explicit class definition in Java. However, that
analogy is not explicit in the code, 'Class' is only a convenient
description for all of the interrelated code that is used to specify the
nature of a new object of that 'Class' created with the MyObject
function and the - new - keyword.

It is convenient for programmers who are familiar with object orientated
languages that explicitly define "Class" structures (such as Java) to
apply that term as a label for the totality of JavaScript code that will
be used to create object instances and to extend that label to include
the concept of an object being an instance *of* a particular Class (it
was created with a single set of instance defining code). So "Class" is
also used as a label for the "type" of an object (though JavaScript,
unlike Java, is loosely typed so the "type" that is named by the "Class"
is in the programmers understanding of the code and not a part of the
ECMA Script language, Internally it is just another Object).
Man, I really want the next words you say to be, "Actually I think
you *do* get it, Daniel, but for God's sake, man, work on your
ability to precisely explain what you mean!"

Sorry, I am not going to say that until I can see that you have
understood the behaviour of the in-line one-off function call. You are
getting close and Lasse has posted a very explicit description so I am
confident that you will have it under your belt next time.

As far as precise explanations, that goes both ways. If I was better at
explaining then you might find understanding easier. Seeing where I fail
to get my point across helps me to refine my explanation, which makes
this whole exchange worthwhile in itself. I think that you are doing
your half of the conversation very well. In describing your
understanding at every stage I think that I can see which aspects of the
process I am failing to properly convey.
If nothing else, I truly understand why

alert(function(){ return function() { return true; }}()());

Gives me an alert box with "true" written in it.

Excellent! One more small step and your there.

Richard.
 
D

Daniel

Lasse Reichstein Nielsen said:
Years of practice writing academic English will do that to you. I can
talk for hours about closures, but I have little to no knowledge of

Ah, that explains it then =)
The constructor variable has not been declared local by a "var
constructor" declaration. Therefore it defaults to being global.

Ofcourse =)
The value of the variable "oneOff" is a function. That function's body
contains 'document.write(" 2")'. When writing "new oneOff()" you use
that function as a constructor, but that includes calling it as a function.
The "document.write" is executed as part of the expression "new oneOff()".

So yes.
Needless detail on how objects are created:

Never needless =) But most of it wasn't news to me. One thing seems a bit
odd to me, though:
Since there are no classes in Javascript, the term "constructor" might
also be a little misleading. As I said, any function can be used as a
constructor. What happens when you write
new foo(42);
is that you call the function "foo" with the argument "42". However,
where a normal function call of that kind would have set the "this"
reference to the global object, and a method invocation would set
"this" to the object of the method, the "new" makes sure that the
"this" keyword refers to an entirely new object. If the foo function
doesn't return something (or if it returns something that is not an
object), that new object is the value of the entire expression. If
it returns another object, they object will be the value of the "new"
expression.

---
function foo(x) {
this.n=x;
}

foo(37); /* sets this.n = 37 with this == global object */

What purpose could this global object serve? And exactly where does it
exist? Since its properties are accessible without a suffix, i.e. global,
It'd be tempting to think of it as a part of the window.document object. Or
are global objects not bound to the window.document object either - are only
objects created with "var blahblah" or "self.blahblah" bound to
window.document? With frames, for example, I can access global variables in
another frame via the document path.
 
D

Daniel

Richard Cornford said:
Ops, that's my fault. If you look closely at the way I have spelled
function you will notice that the t and the i have been transposed. One
of the hazards of touch typing into a word processor instead of a
syntax-highlighting text editor. Though I am surprised that I did not
notice Word complaining about the spelling, but there is a tendency to
ignore highlighted spelling mistakes when entering code in Word. Sorry
if that was confusion, correct the spelling an it will work as
advertised.

No, actually it's my fault ;) I did see the typo and fixed it (I usually
write "functino" myself), but I called it using "new" which was obviously a
mistake.
My reason for stressing that the assignment operation had a left hand
side (var MyObject) and a right hand side (all the rest of the
statement) was to try and explain how MyObject was only ever assigned
the end result of the right hand side. There is not "hijacking" because
the only value that is ever associated with the MyObject variable is a
reference to a function object that was originally created as the inner
function "constructor" within the execution context of the one-off
function execution.

And that's *almost* how I saw it. I didn't see a sequence of assignments
going on, but a sequence of evaluations, with one final assignment. I simply
needed to visualize the "intermediate results" to properly conceive the
sequence and the final effect :p I just couldn't see that the Mr. One-Off
and his trail of closure came into play at the moment of assigning MyObject
its value. I wanted Mr. One-Off to come along for the ride =)

In other words, the final knot I needed to tie (should've been the first
knot) was that after something like this -

var blahblah = function() {
constructor = function() {
};
return constructor;
}();

- blahblah already holds the reference to constructor, and I wanted it to
hold a reference to the function expression until blahblah was called for
the first time. Which is also why the hijacking term was not only confusing
but plain out wrong - there's no reference to hijack =)

I also think that I held on to that illusion so long because I couldn't see
anything functionally proving it to be false, the difference between
illusion and fact was essentially the point of time the anonymous function
was "evaluated" or "executed", and delaying the evaluation demanded that a
ficticious reference to the function expression had to exist. If such a
reference did indeed exist, and it worked the way I wanted it too, I don't
think it would've caused any programmatical problems (at least not in this
context), it would probably just require a rewrite of the Javascript
specifications ;)

The facts are much more logic and easier to understand - it's kinda funny
(or, very irritating ;) that I didn't see them the first time.
You seem to be seeing too much happening at once and Lasse is right,
parenthesising the original statement should make the real sequence of
events clearer.

Which is also what you say here =)

And here:
At the point of executing:-

var objectInstance = MyObject();

- the MyObject variable already contains a reference to the inner
function that was defined with the name "constructor". The one-off
function has already been executed and done its work, At this point The
one-off function has no accessible references and will never be executed
again.
....

The template for an ECMA Script object is much more loosely defined, and
it is also mutable (though you wouldn't often want to do that). If my

Don't want to start another long thread that should have its own topic, but
what's "mutable"?
original class was defined in the more traditional JavaScript way, as a
separate constructor function and as properties of that function and its
prototype object (the private members must now be public members as
there are no closures to contain them), the results would look like:-

function MyObject(){
this.id = id;
this.self = this; //pointless in an object with no inner functions
this.index = MyObject.incrementCounter();
}
MyObject.prototype.getIndex = function(){
return this.index;
}
MyObject.counter = 0;
MyObject.incrementCounter = function(){
MyObject.counter++;
}
MyObject.getNoOfInsts = function(){
return counter;
}
MyObject.prototype.getId = function(){
return this.id;
}

It's really nice to see it like this, very familiar =)
Sorry, I am not going to say that until I can see that you have
understood the behaviour of the in-line one-off function call. You are
getting close and Lasse has posted a very explicit description so I am
confident that you will have it under your belt next time.

How about now? =)
As far as precise explanations, that goes both ways. If I was better at
explaining then you might find understanding easier. Seeing where I fail
to get my point across helps me to refine my explanation, which makes
this whole exchange worthwhile in itself. I think that you are doing
your half of the conversation very well. In describing your
understanding at every stage I think that I can see which aspects of the
process I am failing to properly convey.

Good to hear this is not just to my benifit. =)
Excellent! One more small step and your there.

Actually, when I said I understood that, I must have been either lying or
already "there" but too daft to realize it, because if I truly understood
that as I understood (read: misunderstood) the real issue, then I would have
had to believe that the alert box would write out "function" (at least if
suffixed by a typeof), since that would have been the "reference to hijack"
according to my illusion! Or maybe I just had to connect the simple with the
advanced :)

At least now, I TRULY truly understand it ;)

Thank you, both of you!

Daniel
 
L

Lasse Reichstein Nielsen

Daniel said:
What purpose could this global object serve?

The global object is the repository of global variables. As such, it is
effectively the top of all scope chains, so it is always in scope. That
is what makes global variables possible at all.
And exactly where does it exist?

Inside the Javascript interpreter. The existence of the global object
is given by the ECMAscript standard, and all Javascript code is executed
in the context of one global object.

For each function call, the interpreter creates a local scope, the
so-called "variable object", where the parameters and local variables
are properties. These variable objects are not accessible from
javascript, so you cannot use them as objects in your code, they are
merely described as objects in the specification. That allows
implementations to optimize these objects.

The global object is different, since it can be, and typically is,
visible to the javascript code.
Since its properties are accessible without a suffix, i.e. global,
It'd be tempting to think of it as a part of the window.document
object.

Quite the opposite.

One of the properties of the global object in browsers has the name
"window". That is why you can write "window" directly in Javascript -
it is a global variable, i.e., a property of the global object.

The value of the "window" property is a reference to an object. It
is in fact a reference to the global object itself. So is the "self"
property, and in some cases also "parent" and "top". The global object
would survive, even if you changed what all these references points
to.
Or are global objects not bound to the window.document
object either - are only objects created with "var blahblah" or
"self.blahblah" bound to window.document?

The global object is the base scope for for javascript executed as a
"Program" (as opposed to a "function body" or "eval block"). That
means that top-level variable declarations end up in the global
object, just like local variable declarations of function bodies end
up in the variable object of the function application. Ditto for
function declarations.

If you write
x=y;
and neither are declared as local or global variables, then you get an
error. When no variables are declared, the "y" is checked in the global
object, and it doesn't exist, so you can't find its value. That is an error.

You could write "window.y" which would merely give "undefined", because
that is property access, not variable lookup, even though the resulting
property would be the same.

If "y" was defined, but "x" wasn't, then "x" would also be searched
for in the global object. However, it is not an error that it is
undefined, since we don't attempt to read it. Instead a new property
called "x" of the global object is created, and the value of "y" is
stored in it.
With frames, for example, I can access global variables in another
frame via the document path.

That is correct. The global objects of one execution context might be
accessible as a normal object in another execution context. That
doesn't change that each execution has only one global object.

When javascript code is evaluated, the global object is the "window"
object (or really the opposite: the "window" object is the global
object) of the window from which the code was called.

/L
 
D

Daniel

Lasse Reichstein Nielsen said:
The global object is the repository of global variables. As such, it is
effectively the top of all scope chains, so it is always in scope. That
is what makes global variables possible at all.

Oooookayyy... When you wrote -
function foo(x) {
this.n=x;
}

foo(37); /* sets this.n = 37 with this == global object */

- I read foo as "becoming a global object", but ofcourse, since foo is
called without "new", there's no object instantiation, foo acts as a
function only, and "this" references *the* global object. Sloppy me! =)
Quite the opposite.
The value of the "window" property is a reference to an object. It
is in fact a reference to the global object itself. So is the "self"
property, and in some cases also "parent" and "top". The global object
would survive, even if you changed what all these references points
to.

Ah, this explains why global object values are accessible from other frames
with path dot notation AND locally without, since that's how any other
object works.

Thanks for this, I've really learned alot these few days =) This shouldn't
be called a newsgroup, it should be a class-is-in-session-group ;)

I think I'm about ready for a nice, long weekend =)


Daniel
 
R

Richard Cornford

Don't want to start another long thread that should have its
own topic, but what's "mutable"?

The opposite of immutable (which will be in your dictionary and means:
unchanging, unalterable, ageless.). Consider:-

function TestObject(){
this.getIndex = getIndex_TO;
}

TestObject.prototype.index = 0;

TestObject.prototype.incIndex = function(){
this.index = this.index + 1;
}

var getIndex_TO = function(){
return this.index + 1;
}

- if you created 50 objects with that constructor they would all be
created with the same template and exhibit the same behaviour. But if
you then executed:-

getIndex_TO = function(){
return this.index * 4;
}

- the next 50 objects would behave differently from the first 50. With
Java all objects of the same Class are created with the same code but in
JavaScript it is possible to make all sorts of changes to the code that
can be used to define a new object while your program is executing.

It would be reasonable to say that the first 50 TestObject instances are
not the same "Class" as the next 50, or to say that the "Class" has
changed. It is more likely the case that if you don't treat your object
defining code as immutable then the whole "Class" concept does not
really fit in with JavaScript at all.

Under the vast majority of circumstances modifying the code that will be
used to define a new Object of a particular "Class" is not something
that you would want to do. So "Class" as a concept will fit with
JavaScript. On the other hand, being able to modify it introduces some
interesting and potentially useful possibilities. Consider executing:-

var a = new TestObject();
var b = new TestObject();
a.incIndex();
TestObject.prototype.index = 5;
var c = new TestObject();
alert('a.index = '+a.index+
' b.index = '+b.index+
' c.index = '+c.index)

- with the original TestObject code. When initially reading the -
this.index - value the objects are reading the value from their
prototype. When the - incIndex - method increments the index it will set
a property of the object with the name "index" (masking the value on the
prototype). So changes to the value on the prototype impact upon objects
created before the change was made, but only if they have not already
executed their - incIndex - method and cut themselves of from reading
the value on the prototype.

Of course it is not going to be easy to usefully exploit the fact that
JavaScript offers that level of flexibility.

How about now? =)

yes I actually do think that you get it. :)

Good to hear this is not just to my benifit. =)

There is very little that appears altruistic that is not in reality at
least slightly selfish. During this exchange I have clarified various
details of the process of creating private static members in JavaScript
and improved my ability to explain it clearly. I have also had one of my
misconceptions corrected (thank you Lasse :). Lasse has also sparked a
completely new idea in my mind (that I will be responding to later).

Thank you, both of you!

You are welcome.

Richard.
 
D

Daniel

The opposite of immutable (which will be in your dictionary and means:
unchanging, unalterable, ageless.). Consider:-
<code & explanations>

This is actually the object behaviour I know from Actionscript (although I
didn't understand it as thoroughly before this thread), so I'm really glad
to see it's the same behaviour :)
yes I actually do think that you get it. :)

YAY! :p

Good to have my weekend with that one over :)

Have a good one!

Daniel
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top