By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,256 Members | 1,700 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,256 IT Pros & Developers. It's quick & easy.

OO Javascript for AJAX encapsulation

P: n/a
I'm reading 'Ajax in Action', (one of the best of the many tech books
I've read) and there's an example that I just don't fully understand.
If you happen to have the book, it's on page 75. I'm hoping someone can
enlighten me.

var loader = this;
this.req.onreadystatechange = function() {
loader.onReadyState.call(loader);
}

My question is this: Why is loader assigned a value of this? Why not
just use this? I'm assuming objects in JS are passed by value so a
copy of the object is made, but I still don't fully understand how the
context changes.

Thanks in advance.

Larry

Oct 6 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Hi,

lk********@gmail.com wrote:
I'm reading 'Ajax in Action', (one of the best of the many tech books
I've read) and there's an example that I just don't fully understand.
If you happen to have the book, it's on page 75. I'm hoping someone can
enlighten me.

var loader = this;
this.req.onreadystatechange = function() {
loader.onReadyState.call(loader);
}

My question is this: Why is loader assigned a value of this? Why not
just use this? I'm assuming objects in JS are passed by value so a
copy of the object is made, but I still don't fully understand how the
context changes.

Thanks in advance.

Larry
Ah, closure...

OK, it's probably one of the most difficult concepts to understand in
JavaScript, so bear with me.

The idea is this: An event handler can only be assigned a parameter-less
function. In the case of onreadystatechange, the function assigned is an
anonymous, parameter-less function.

However, it would be nice to access parameters, for example (in that
case) the object encapsulating the XmlHttpRequest. But, when the
function is executed, the context has changed, because it's a global
function (it is not assigned to the object (that wouldn't work), it is
executed in the context of the global object. In web browsers, the
global object is the window. When the function is executed, "this"
refers to the window, as a simple test would show.

Thankfully, JavaScript has closure. It means that, when a function is
defined, its (external) context is also saved, and will be accessible
from inside the function. Variables defined externally to the function
will be visible and accessible when the function is called, whatever the
function's context is!

So what the code does here is: Save the reference contained in "this" in
a variable external to the function (loader), then define the anonymous,
parameter-less function. When the function will be called, thanks to
closure, the external variable will be accessible.

Use closure with care, because it can be the source of memory leaks
(through circular references), especially in AJAX applications, where
the page is not reloaded very often.

Does that make sense?

HTH,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
PhotoAlbum: http://www.galasoft-LB.ch/pictures
Support children in Calcutta: http://www.calcutta-espoir.ch
Oct 6 '06 #2

P: n/a
Here's a simple example of what Laurent wrote :

var Test = function() {

// the context 'this' is the current Test object instance
this.msg = 'This is a test function';

var loader = this; // save closure

this.display = function() {
alert( 'context=' + this + ', this.msg=' + this.msg + '\n' +
'saved context=' + loader + ', loader.msg=' + loader.msg );
}

}

var test1 = new Test();
var test2 = test1.display; // assign test2 the function reference

test1.display(); // call the object function
test2.call(); // we can just use test2() since test2 is a function
now

Need it be more explanations ?

Oct 7 '06 #3

P: n/a
VK
An event handler can only be assigned a parameter-less
function.
Maybe it would be better to use the regular term "function reference":
"An event handler can only be assigned a function reference or an
expression returning function reference".
"parameter-less function" is a bit unclear: someone can take it as if
event handler / anonymous functions cannot have arguments (while they
can).

After that it's the best description of the "incontinence of [this]"
phenomenon posted at c.l.j. for a rather while.
P.S. <OT>
In this aspect "Private Members in JavaScript" contains one statement
which is not totally correct:
function foo() {} // 1)
and
var foo = function() {}; // 2)
are not equal there 2) is just a <q>shortcut form</qof 1)
In the first case we are declaring named function "foo" (one memory
item).
In the second case we are creating variable "foo" and assigning to it
the result of the right-hand expression. This result is a reference to
the anonymous function (two memory items: our anonymous function and
"foo" holding a reference to it).
Most of the times it is not important, but sometimes useful to know.
<OT>

Oct 7 '06 #4

P: n/a
VK wrote:
>An event handler can only be assigned a parameter-less
function.

Maybe it would be better to use the regular term "function
reference": "An event handler can only be assigned a
function reference or an expression returning function
reference". "parameter-less function" is a bit unclear:
someone can take it as if event handler / anonymous
functions cannot have arguments (while they can).

After that it's the best description of the "incontinence
of [this]" phenomenon posted at c.l.j. for a rather while.
One of the many things that make your opinions worthless is quibbling
about the terminology used by others wile attaching terms like
"incontinence" to behaviour that is specified, consistent, reliable and
completely predictable.
P.S. <OT>
You have also still not understood that the criteria for 'off topic' is
determined by the topic of the group (i.e. javascript) not by the subject
headers of any particular thread. The following, while pointless, is
about javascript.
In this aspect "Private Members in JavaScript" contains one
statement which is not totally correct:
You are neglecting to take into consideration the fact that you have
virtually no technical understanding of javascript. Whatever may appear
to be incorrect to you will not necessarily (indeed, will rarely)
actually be incorrect.
function foo() {} // 1)
and
var foo = function() {}; // 2)
are not equal there 2) is just a <q>shortcut form</qof 1)
In the first case we are declaring named function "foo"
(one memory item).
In the second case we are creating variable "foo" and assigning
to it the result of the right-hand expression. This result is
a reference to the anonymous function (two memory items: our
anonymous function and "foo" holding a reference to it).
Nonsense. In both cases a function object is created and a reference to
that function is assigned to a property of the Activation/Variable object
for the execution context. The implications for memory consumption are
identical in both cases. The only significant difference between the two
is when the various parts of the process happen.

In both cases a property of the Activation/Variable object with the name
"foo" is created during variable instantiation. In the first case a
function object is created and a reference to that function assigned to
the value of that property also during variable instantiation. In the
second case the creation of the function object does not happen until the
function expression is evaluated, and the assignment of a reference to
that function is not assigned to the "foo" property until the assignment
expression is evaluated.
Most of the times it is not important, but sometimes useful
to know.
<OT>
As your assertion about "memory item"s is nonsense it is unlucky that
'knowing' it will ever be useful. Indeed, like most of your superstitious
beliefs about javascript, 'knowing' it is most likely to be positively
harmful. Which goes some way to explaining why you don't even understand
the javascript code you write.

Richard.
Oct 7 '06 #5

P: n/a
VK

Richard Cornford wrote:
behaviour that is specified, consistent, reliable and
completely predictable.
Does it mean that any properly reported bug becomes a legitimate
feature? :-) Because your description fits perfectly for a bug listed
at say Microsoft KB or Bugzilla, acknowledged by producer, having a
written workaround.

Yet there are different opinions on the incontinence of [this] problem,
so I'm using a neutral term "phenomenon" for it. After all say Eskimos
too paddle face forward and they consider white people paddling with
all another part of body forward totally ridiculous. Who's right, who's
wrong - no one, really - it's all question of traditions.
You have also still not understood that the criteria for 'off topic' is
determined by the topic of the group (i.e. javascript) not by the subject
headers of any particular thread.
That can be true for some "What is true love?" public forum :-), but
for a technical newsgroup the discussion should stay on the subject: or
simply change the subject line accordingly to go on a new branch, or
better yet start a new discussion. Whoever will search the archives for
an answer do not necessary have to read all and every side posts.

function foo(){} vs. var foo = function(){}
In both cases a function object is created and a reference to
that function is assigned to a property of the Activation/Variable object
for the execution context. The implications for memory consumption are
identical in both cases.
I did not mean any memory consumption considerations, they are
negligible. There are other fine-tune effects you have to account
sometimes.

In the first case we have a function declaration. In the second case we
have an assignment, so the right-hand expression is being evaluated and
the result assigned to the left-hand operator. The result of a function
expression is a reference to the function just created during the
evaluation. If you have any IE handy (or Netscape 3.x - 6.x) you can
see the difference even without any monitoring software. Simply use a
named function instead of anonymous one in your expression:

<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">
var bar = void function f(){};
alert(typeof bar);
alert(typeof f);
</script>
</head>
<body>
</body>
</html>

void prevents bar from receiving evaluation result, but it doesn't stop
"function f(){};" expression to create new function object.

On Firefox and Opera it can be tricky to see that, because they have
patched function expression visibility scope to be in accordance with
ECMAScript prescriptions. Here you need some monitoring software.

Once again: it is not about memory usage, the difference is negligible.

Oct 8 '06 #6

P: n/a
VK wrote:
Richard Cornford wrote:
>behaviour that is specified, consistent, reliable and
completely predictable.

Does it mean that any properly reported bug becomes a
legitimate feature? :-) Because your description fits
perfectly for a bug listed at say Microsoft KB or
Bugzilla, acknowledged by producer, having a written
workaround.
You don't know what you are talking about (hence the absence of any
references to bug reports relating to the handling of - this - in
ECMAScript implementations).

<snip>
>You have also still not understood that the criteria for
'off topic' is determined by the topic of the group (i.e.
javascript) not by the subject headers of any particular
thread.

... but for a technical newsgroup the discussion should
stay on the subject:
Nonsense, and frequently impractical as subject headers are frequently so
poorly worded that attempting to restrict answers to the subject in the
subject header would preclude providing any answer to the question at
all.
or simply change the subject line accordingly to go on a
new branch, or better yet start a new discussion.
Nonsense.
Whoever will search the archives for an answer do not
necessary have to read all and every side posts.
People searching the archives are unlikely to restrict their searches to
subject headers.
function foo(){} vs. var foo = function(){}
>In both cases a function object is created and a reference
to that function is assigned to a property of the
Activation/Variable object for the execution context.
The implications for memory consumption are identical
in both cases.

I did not mean any memory consumption considerations,
Then what did you mean by mentioning memory in "In the first case we are
declaring named function "foo" (one memory item)" and " This result is a
reference to the anonymous function (two memory items: our anonymous
function and "foo" holding a reference to it)"? If you write this rubbish
there is always a chance that people will seek meaning in the words you
actually use.

<snip: more irrelevance>
Once again: it is not about memory usage, the difference
is negligible.
So why did you mention memory at all? And why are you now trying to hide
behind the well know bugs in function expressions with optional
Identifiers? The code you were finding fault with contained no Identifier
in the function expression.

Richard.
Oct 8 '06 #7

P: n/a
VK

Richard Cornford wrote:
You don't know what you are talking about (hence the absence of any
references to bug reports relating to the handling of - this - in
ECMAScript implementations).
I'm talking about nailing the object context to some object methods by
using something=this and similar workarounds. We can take it as a
documentation oopsy (on the level of a poopsy). We can take it as a
"documented standard-compliant behavior" and then other languages -
where the method context is always set to the relevant method's owner -
are demonstrating a weird behavior in comparison to javascript. I'm
staying on the first one, anyone is welcome to stay on the second,
"phenomenon" seems appropriate as a term to cover both.

<snip>
Then what did you mean by mentioning memory in "In the first case we are
declaring named function "foo" (one memory item)" and " This result is a
reference to the anonymous function (two memory items: our anonymous
function and "foo" holding a reference to it)"?
I mean what I wrote: that we have different production mechanics and
different results, and it's important to remember in some
circumstances. Rather than jumping on something you don't like to hear
(but being true) get yourself a heaps monitoring tool and check it
yourself. Quick'n'durty proof would be:

<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

// FunctionDeclaration
function f1() {
window.alert(arguments.callee.toString());
}

// FunctionExpression
var f2 = function(){window.alert(arguments.callee.toString( ));}

function init() {
f1();
f2();
}

window.onload = init;
</script>
</head>
<body>
</body>
</html>

Oct 8 '06 #8

P: n/a
VK wrote:
Richard Cornford wrote:
>You don't know what you are talking about (hence the absence
of any references to bug reports relating to the handling of - this
- in ECMAScript implementations).

I'm talking about nailing the object context to some object methods by
using something=this and similar workarounds. We can take it as a
documentation oopsy (on the level of a poopsy). We can take it as a
"documented standard-compliant behavior" and then other languages -
where the method context is always set to the relevant method's owner -
are demonstrating a weird behavior in comparison to javascript.
What other languages may do is irrelevant. They will be doing what
their specifications say they should do, and javascript does exactly
what its specification says it should do. Expecting javascript to be
visual basic, Java or C++ is just foolish.
I'm staying on the first one, anyone is welcome to stay on the
second, "phenomenon" seems appropriate as a term to cover both.
For other people those are not the alternatives, as for them
understating javascript is also a possibility.
><snip>
>Then what did you mean by mentioning memory in "In the first case
we are declaring named function "foo" (one memory item)" and " This
result is a reference to the anonymous function (two memory items:
our anonymous function and "foo" holding a reference to it)"?

I mean what I wrote: that we have different production mechanics and
different results,
Rubbish. The difference is only in when the properties of the
Activation/variable object are created, when the function object is
created and when the reference to the function object is assigned to
the property of the Activation/Variable object. The way in which the
properties are created on the Activation/Variable object is the same in
both cases. The way in which a function object is created is the same
in both cases, and the nature and outcome of the assignments are the
same in both cases.
and it's important to remember in some
circumstances.
The difference in when things happen is quite important in javascript
programming.
Rather than jumping on something you don't like to hear
(but being true) get yourself a heaps monitoring tool and check it
yourself.
Check what exactly? What is it that you expect to be observed? You have
not yet clearly stated what exactly it is about assertion you were
commenting on that you found objection to.

Quick'n'durty proof would be:
Proof of what exactly?
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

// FunctionDeclaration
function f1() {
window.alert(arguments.callee.toString());
}

// FunctionExpression
var f2 = function(){window.alert(arguments.callee.toString( ));}

function init() {
f1();
f2();
}

window.onload = init;
</script>
</head>
<body>
</body>
</html>
So what does that prove? We know that function objects have - toString
- methods that return implementation dependent values, what is learnt
by seeing them in action?

Richard.

Oct 8 '06 #9

P: n/a
VK
I'm talking about nailing the object context to some object methods by
using something=this and similar workarounds. We can take it as a
documentation oopsy (on the level of a poopsy). We can take it as a
"documented standard-compliant behavior" and then other languages -
where the method context is always set to the relevant method's owner -
are demonstrating a weird behavior in comparison to javascript.
I'm staying on the first one, anyone is welcome to stay on the
second, "phenomenon" seems appropriate as a term to cover both.

For other people those are not the alternatives, as for them
understating javascript is also a possibility.
There is also an option to understand things but do not agree with them
despite they are written by some authority and "sealed by the big
seal". Mr.Crockford is definitely someone who knows at least "a little
bit" about javascript :-), and at least once he called an error "an
error". I do not imply a relationship of any kind with Mr.Crockford (I
have none), and maybe he currently already like to use the "this
nailing" and maybe he's currently sorry for using once the word "error"
- I have no idea. I'm just reminding you of an option to understand but
do not agree with an official regulation. But this option is not an
option for everyone, of course (coming back to the circle with the
"documentation bug" discussion we already had before).
Then what did you mean by mentioning memory in "In the first case
we are declaring named function "foo" (one memory item)" and " This
result is a reference to the anonymous function (two memory items:
our anonymous function and "foo" holding a reference to it)"?
I mean what I wrote: that we have different production mechanics and
different results.
Quick'n'durty proof would be:
Proof of what exactly?
Of what I just wrote, what else? :-)
<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

// FunctionDeclaration
function f1() {
window.alert(arguments.callee.toString());
}

// FunctionExpression
var f2 = function(){window.alert(arguments.callee.toString( ));}

function init() {
f1();
f2();
}

window.onload = init;
</script>
</head>
<body>
</body>
</html>
So what does that prove? We know that function objects have - toString
- methods that return implementation dependent values, what is learnt
by seeing them in action?
So we have cross-browser consistent umplementation difference of
toString() method for FunctionDeclaration and FunctionExpression. :-))

Oct 8 '06 #10

P: n/a
VK wrote:
>>I'm talking about nailing the object context to some object methods by
using something=this and similar workarounds. We can take it as a
documentation oopsy (on the level of a poopsy). We can take it as a
"documented standard-compliant behavior" and then other languages -
where the method context is always set to the relevant method's owner -
are demonstrating a weird behavior in comparison to javascript.
I'm staying on the first one, anyone is welcome to stay on the
second, "phenomenon" seems appropriate as a term to cover both.

For other people those are not the alternatives, as for them
understating javascript is also a possibility.
<snip>
- I have no idea. I'm just reminding you of an option to understand
but do not agree with an official regulation. But this option is not
an option for everyone, of course
Disagreeing with a programming language doing what it is specified to
do is pointless and unproductive. While understanding what it has been
specified to do is extremely useful in writing code that you understand
yourself.
(coming back to the circle with
the "documentation bug" discussion we already had before).
A high point in your posting of worthless nonsense.
>>>Then what did you mean by mentioning memory in "In the first case
we are declaring named function "foo" (one memory item)" and " This
result is a reference to the anonymous function (two memory items:
our anonymous function and "foo" holding a reference to it)"?
>
I mean what I wrote: that we have different production mechanics and
different results.
Quick'n'durty proof would be:
Proof of what exactly?

Of what I just wrote, what else? :-)
So how does it prove "different production mechanics and different
results"? As far as I can see you have done no more than demonstrate
that when the - toString - method of function objects does return
something representing the original source code of the function
differing source code is apparent in that representation. That says
nothing about the "results" being different or anything about
"production mechanics" (whatever "production mechanics" is supposed to
mean).

<snip>
>So what does that prove? We know that function objects have - toString
- methods that return implementation dependent values, what is learnt
by seeing them in action?

So we have cross-browser consistent
How many browsers did you look in? One, Two?
umplementation difference of
toString() method for FunctionDeclaration and FunctionExpression. :-))
What evidence have you that the toString methods are different for
FunctionDeclarations and Function Expression?

Richard.

Oct 8 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.