Google グループは Usenet の新規の投稿と購読のサポートを終了しました。過去のコンテンツは引き続き閲覧できます。
Dismiss

Closures Explained

閲覧: 384 回
最初の未読メッセージにスキップ

MartinR...@gmail.com

未読、
2008/10/10 11:38:132008/10/10
To:
I've rewritten a short article explaining closures in JavaScript.
It's
at:

http://www.martinrinehart.com/articles/javascript-closures.html

A big Thank You to PointedEars and Jorge for helping me get closer to
the truth.

David Mark

未読、
2008/10/10 11:44:502008/10/10
To:
On Oct 10, 11:38 am, MartinRineh...@gmail.com wrote:
> I've rewritten a short article explaining closures in JavaScript.
> It's
>  at:
>
> http://www.martinrinehart.com/articles/javascript-closures.html
>

It gets off to a dubious start:

"I had the best books (Flanagan, Resig, Crockford)"

Flanagan has been proven clueless and Resig's books belong in the
comedy racks (or on a bonfire.)

And there isn't much there. This is a far superior article:

http://www.jibbering.com/faq/faq_notes/closures.html

Lasse Reichstein Nielsen

未読、
2008/10/10 12:07:562008/10/10
To:
MartinR...@gmail.com writes:

Comments:

In the example:
function outer() {
// args here
// code here
function inner() {
// more args and code
}
} // end of outer()
the "args here" comment seems slightly misleading. Arguments goes
between the parentheses. Maybe use:
function outer(/* arguments here *) {
instead.

The sentence "A closure is a bundle of data and code that manipulates
that data" is still indistinguishable from the description of an
Object.

A closure is a piece of code together with a binding of values to the
free variables of that code.

A free variable is one that occur in the code, but is not declared
there.

The next sentence, "In JavaScript it's a function with data that's
unavailable, except to the function." is closer, but also wrong.
The data, and even the bindings, might be available to other code too.

Example:

function pair(a,b) {
return {setFst : function(x){a=x;},
setSnd : function(x){b=x;},
sum : function() { return a+b; }};
}

var p = pair(2,4);
var s = p.sum; // s holds a clousre, but its data and bindings
// are available through, e.g., pair.setFst:
alert(s());
p.setFst(38);
alert(s());

So, what you describe as "What is a Closure?" isn't correct. It is
one use of a closure: to create functions with shared private variables.
It seems this use of closures is the focus of your page, but it should
really be named "private variables in Javascript, using closures" instead.

Closures are MUCH more than just that, e.g.:

function curry(f) {
return function(a) {
return function (b) {
return f(a,b);
}
}
}
function sum(a,b) { return a+b;};
var csum = curry(sum);
var inc = csum(1);
var addFive = csum(5);
alert([inc(41),addFive(37)]);


or it can be used to express something complicated in a simpler way:

function map(arr,f) {
var res = [];
for(var i = 0; i < arr.length; i++) {
res[i] = f(arr[i]);
}
return res;
}

function cross(arr1,arr2) {
return map(arr1, function(x1) {
return map(arr2, function(x2) { return [x1,x2]; });
});
}

var pair_matrix = cross([1,2,3],[4,5,6]);
// pair_matrix ==
// [[[1,4],[1,5],[1,6]],
// [[2,4],[2,5],[2,6]],
// [[3,4],[3,5],[3,6]]]

(try doing it shorter using nested loops :)

And to prettify it:

alert(map(pair_matrix, function(a1) {
return map(a1, function(a2) {
return "(" + a2[0] + "," + a2[1] +")";
}).join(",");
}).join("\n"));

To put it bluntly: Closures allow you to write functional programs.
If only we had tail-calls, it would be perfect :)

/L
--
Lasse Reichstein Nielsen
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'

MartinR...@gmail.com

未読、
2008/10/10 13:06:522008/10/10
To:

David Mark wrote:
> "I had the best books (Flanagan, Resig, Crockford)"
>
> Flanagan has been proven clueless and Resig's books belong in the
> comedy racks (or on a bonfire.)
>
> And there isn't much there. This is a far superior article:
>
> http://www.jibbering.com/faq/faq_notes/closures.html

Flanagan is listed in the FAQ as the best JavaScript book.

The jibbering article is good. However, it's 10 times longer. My goal
was to give some poor JavaScripter wannabe the basic idea so s/he
could get on with writing code.

MartinR...@gmail.com

未読、
2008/10/10 13:18:362008/10/10
To:
On Oct 10, 12:07 pm, Lasse Reichstein Nielsen <lrn.unr...@gmail.com>
wrote:

> the "args here" comment seems slightly misleading.
> ... between the parentheses. Maybe use:
Stupid me. That's 'vars'. Double dumb: the rewrite was on my computer,
not ULd. Fixed that, too.

I'll go through the rest of your points when I've got the time they
seem to deserve. Thanks.

David Mark

未読、
2008/10/10 14:37:122008/10/10
To:
On Oct 10, 1:06 pm, MartinRineh...@gmail.com wrote:
> David Mark wrote:
> > "I had the best books (Flanagan, Resig, Crockford)"
>
> > Flanagan has been proven clueless and Resig's books belong in the
> > comedy racks (or on a bonfire.)
>
> > And there isn't much there.  This is a far superior article:
>
> >http://www.jibbering.com/faq/faq_notes/closures.html
>
> Flanagan is listed in the FAQ as the best JavaScript book.
>

I thought it was listed as the lesser evil. It is not an endorsement.

dhtml

未読、
2008/10/10 16:33:582008/10/10
To:

http://jibbering.com/faq/#onlineResources

| Although many books have been reviewed, most are quite bad and cannot
| be recommended.
|
| The following list of books been approved by CLJ regulars after
| critical review.
|
...

Garrett

Jorge

未読、
2008/10/10 17:33:382008/10/10
To:
On Oct 10, 5:44 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
> It gets off to a dubious start:
>
> "I had the best books (Flanagan, Resig, Crockford)"
>
> Flanagan has been proven clueless and Resig's books belong in the
> comedy racks (or on a bonfire.)


A doubt a book by you or Mr. Speck would be better nor more
understandable nor more comprehensible. And sure you the Mr. I'm
perfect clan have your own dose of JS misunderstandings as well...
Nobody is perfect, no, not even Mr. Flanagan.

But because there are a couple of things or three that aren't 100%
perfect in 994 pages it doesn't mean that overall it's not an
excellent book.
Excellent means well above others, first-class. It's excellent.

--
Jorge.

David Mark

未読、
2008/10/10 19:31:402008/10/10
To:
On Oct 10, 5:33 pm, Jorge <jo...@jorgechamorro.com> wrote:
> On Oct 10, 5:44 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
>
>
> > It gets off to a dubious start:
>
> > "I had the best books (Flanagan, Resig, Crockford)"
>
> > Flanagan has been proven clueless and Resig's books belong in the
> > comedy racks (or on a bonfire.)
>
> A doubt a book by you or Mr. Speck would be better nor more

Me or who?

> understandable nor more comprehensible. And sure you the Mr. I'm

What do you know about some hypothetical book?

> perfect clan have your own dose of JS misunderstandings as well...
> Nobody is perfect, no, not even Mr. Flanagan.

Where are you going with this?

>
> But because there are a couple of things or three that aren't 100%
> perfect in 994 pages it doesn't mean that overall it's not an
> excellent book.
> Excellent means well above others, first-class. It's excellent.

Which "it" are you even talking about? AFAIK, they are all a waste of
money.

Thomas 'PointedEars' Lahn

未読、
2008/10/10 20:26:502008/10/10
To:
dhtml wrote:
> David Mark wrote:
>> On Oct 10, 1:06 pm, MartinRineh...@gmail.com wrote:
>>> David Mark wrote:
>>>> "I had the best books (Flanagan, Resig, Crockford)"
>>>> Flanagan has been proven clueless and Resig's books belong in the
>>>> comedy racks (or on a bonfire.)
>>>> And there isn't much there. This is a far superior article:
>>>> http://www.jibbering.com/faq/faq_notes/closures.html
>>> Flanagan is listed in the FAQ as the best JavaScript book.
>>
>> I thought it was listed as the lesser evil. It is not an endorsement.
>
> http://jibbering.com/faq/#onlineResources

You meant <http://jibbering.com/faq/#books>.

> | Although many books have been reviewed, most are quite bad and cannot
> | be recommended.
> |
> | The following list of books been approved

A "has" was missing if the statement was correct in the first place.

> by CLJ regulars after critical review.

^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
Double nonsense.


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>

RobG

未読、
2008/10/10 20:37:332008/10/10
To:
On Oct 11, 6:33 am, dhtml <dhtmlkitc...@gmail.com> wrote:
> David Mark wrote:
> > On Oct 10, 1:06 pm, MartinRineh...@gmail.com wrote:
> >> David Mark wrote:
[...]

> >>> And there isn't much there.  This is a far superior article:
> >>>http://www.jibbering.com/faq/faq_notes/closures.html
> >> Flanagan is listed in the FAQ as the best JavaScript book.
>
> > I thought it was listed as the lesser evil. It is not an endorsement.
>
> http://jibbering.com/faq/#onlineResources
>
> |  Although many books have been reviewed, most are quite bad and cannot
> | be recommended.
> |
> | The following list of books been approved by CLJ regulars after
> | critical review.

I would not include the phrase "after critical review", which infers
that a number of CLJ regulars have read it cover-to-cover and
commented on or approved all the facts presented. I don't recall
anyone here claiming to have done that, much less a sufficient number
of regulars for the statement to be true.

The book presents a number of topics outside the focus of this group
related to HTML, CSS, XML and others - there's even a section on E4X.
I don't recall anyone commenting on those sections, nor are those
topics regularly discussed here in any depth.

The general opinion (not held by everyone, but most I think) is that
it is the best of a bad lot. That sentiment should be maintained in
the text of the FAQ.


--
Rob

Thomas 'PointedEars' Lahn

未読、
2008/10/10 20:38:082008/10/10
To:
MartinR...@gmail.com wrote:
> I've rewritten a short article explaining closures in JavaScript.
> It's at:
>
> http://www.martinrinehart.com/articles/javascript-closures.html

| Unlike most JavaScript attributes (remember: all JavaScript variables are
| attributes)

"JavaScript", as understood in your article, has objects (e.g. Function
objects). Objects may have *properties* (e.g. `length'). Properties
(internally) may have attributes (e.g. `DontDelete').

Incidentally, your definition of "JavaScript" as "the subset of ECMAScript
that Crockford defines in his book, JavaScript: The Good Parts." is useless
to those who have not already bought and read the book.

And that were but the two paragraphs I am currently able to look into.

> A big Thank You to PointedEars and Jorge for helping me get closer to
> the truth.

You are welcome, although I think that you still have a long way to go and
will likely end up with what is in the FAQ, FAQ Notes, and newsgroup
archives. Especially, before trying to explain a complex concept such as
closures, you should get the basics right.


PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

dhtml

未読、
2008/10/10 21:23:402008/10/10
To:
Thomas 'PointedEars' Lahn wrote:
> dhtml wrote:
>> David Mark wrote:
>>> On Oct 10, 1:06 pm, MartinRineh...@gmail.com wrote:
>>>> David Mark wrote:
>>>>> "I had the best books (Flanagan, Resig, Crockford)"
>>>>> Flanagan has been proven clueless and Resig's books belong in the
>>>>> comedy racks (or on a bonfire.)
>>>>> And there isn't much there. This is a far superior article:
>>>>> http://www.jibbering.com/faq/faq_notes/closures.html
>>>> Flanagan is listed in the FAQ as the best JavaScript book.
>>> I thought it was listed as the lesser evil. It is not an endorsement.
>> http://jibbering.com/faq/#onlineResources
>
> You meant <http://jibbering.com/faq/#books>.
>
>> | Although many books have been reviewed, most are quite bad and cannot
>> | be recommended.
>> |
>> | The following list of books been approved
>
> A "has" was missing if the statement was correct in the first place.
>

Indeed. Thank you. I did change the text. I found "Pocket Flanagan" was
summarily reviewed by JR Stockton and Jim Ley.

>> by CLJ regulars after critical review.
> ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
> Double nonsense.
>

Reviews:
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/b3c0f62bff45ea81/3eb57304bd05e85f
http://groups.google.com/group/comp.lang.javascript/msg/e533138dd37f45bf?dmode=source
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/7283898f77fd2a66/c5f145ae807c918e


Douglas Crockford has provided approval on this list as well. (Though
the information is somewhat dated and of an older edition.)
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/46a45facabbd1898/566d10b261b1a9c8

D. Flanagan himself has said that the Pocket Reference was "probably out
of date."
http://groups.google.com/group/comp.lang.javascript/msg/0866b23771e3a75e?dmode=source

>
> PointedEars

Thomas 'PointedEars' Lahn

未読、
2008/10/11 5:23:152008/10/11
To:
dhtml wrote:
> Thomas 'PointedEars' Lahn wrote:
>> dhtml wrote:
>>> David Mark wrote:
>>>> On Oct 10, 1:06 pm, MartinRineh...@gmail.com wrote:
>>>>> Flanagan is listed in the FAQ as the best JavaScript book.
>>>> I thought it was listed as the lesser evil. It is not an endorsement.
>>> http://jibbering.com/faq/#onlineResources
>> You meant <http://jibbering.com/faq/#books>.
>>
>>> | Although many books have been reviewed, most are quite bad and cannot
>>> | be recommended.
>>> |
>>> | The following list of books [has] been approved
>> [...]

As Lasse already said, those postings (especially comments on a few pages
and using that to make assumptions about the rest) do _not_ imply "critical
review".

> Douglas Crockford has provided approval on this list as well. (Though
> the information is somewhat dated and of an older edition.)
> http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/46a45facabbd1898/566d10b261b1a9c8

Douglas Crockford may be knowledgable, but he is _not_ "regulars of CLJ",
and his posting certainly does _not_ imply "*critical* review". He does not
even state the reasons for his recommendation there. Nor does Jim Ley, and
given what Flanagan has posted in c.l.js, their judgement becomes rather
questionable. Ley's is apparently based on nothing but an "ipse dixit"
fallacy. And "not too bad" is certainly no endorsement.

> D. Flanagan himself has said that the Pocket Reference was "probably out
> of date."
> http://groups.google.com/group/comp.lang.javascript/msg/0866b23771e3a75e?dmode=source

Irrelevant.


PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300...@news.demon.co.uk>

Dr J R Stockton

未読、
2008/10/11 10:29:362008/10/11
To:
In comp.lang.javascript message <be9b7575-f8f6-4c31-950e-9ef78d55626a@k3
7g2000hsf.googlegroups.com>, Fri, 10 Oct 2008 10:06:52,
MartinR...@gmail.com posted:

On matters concerning those who need mainly to learn the simple basics,
there's little point in paying any attention to Lahn or Mark. They may
be right; but others will be more helpful.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)

David Mark

未読、
2008/10/11 13:26:012008/10/11
To:
On Oct 11, 10:29 am, Dr J R Stockton <j...@merlyn.demon.co.uk> wrote:
> In comp.lang.javascript message <be9b7575-f8f6-4c31-950e-9ef78d55626a@k3
> 7g2000hsf.googlegroups.com>, Fri, 10 Oct 2008 10:06:52,
> MartinRineh...@gmail.com posted:

>
>
>
>
>
> >David Mark wrote:
> >> "I had the best books (Flanagan, Resig, Crockford)"
>
> >> Flanagan has been proven clueless and Resig's books belong in the
> >> comedy racks (or on a bonfire.)
>
> >> And there isn't much there.  This is a far superior article:
>
> >>http://www.jibbering.com/faq/faq_notes/closures.html
>
> >Flanagan is listed in the FAQ as the best JavaScript book.
>
> >The jibbering article is good. However, it's 10 times longer. My goal
> >was to give some poor JavaScripter wannabe the basic idea so s/he
> >could get on with writing code.
>
> On matters concerning those who need mainly to learn the simple basics,
> there's little point in paying any attention to Lahn or Mark.  They may
> be right; but others will be more helpful.

IIRC, Richard wrote the article in question. I think it is far more
helpful than this new one, even for beginners. Certainly it is the
first article on closures that I ever read and it really opened my
eyes to the possibilities (and pitfalls.)

John G Harris

未読、
2008/10/11 15:31:212008/10/11
To:
On Sat, 11 Oct 2008 at 02:38:08, in comp.lang.javascript, Thomas
'PointedEars' Lahn wrote:

<snip>


>Incidentally, your definition of "JavaScript" as "the subset of ECMAScript
>that Crockford defines in his book, JavaScript: The Good Parts." is useless
>to those who have not already bought and read the book.

<snip>

Moreover, the language Crockford defines isn't JavaScript, or even
javascript. It's a language where you aren't allowed to do

... { ... { ... } ... } ...

but if you want to pervert Crockford's prejudices you are allowed to do

... { ... if (true) { ... } ... } ...

instead.

This is one of the reasons why I think links to the Crockford book
should have a big warning label attached.

John
--
John Harris

Conrad Lender

未読、
2008/10/11 16:58:322008/10/11
To:
On 2008-10-11 21:31, John G Harris wrote:
> Moreover, the language Crockford defines isn't JavaScript, or even
> javascript. It's a language where you aren't allowed to do
>
> ... { ... { ... } ... } ...

Where does he say that?

You're quoting him out of context; JSON wouldn't be possible if nested
curlies weren't allowed. Just a guess, but he was probably talking about
the absence of (traditional*) block scope in JavaScript, and was
suggesting that unnecessary {} blocks shouldn't be used, in order to
avoid confusion. In that context, I would agree with Crockford.

[* yes, I'm aware of 'with' and 'let']

He's pretty picky about which parts he considers "Good", I know, but he
usually gives a reason for his choices. This is not a beginner book, and
definitely not a tutorial or guide; it's a collection of one man's
opinions. I personally found it quite interesting. But then I'm not a
beginner, and I like to read about other people's ideas and approaches,
even if I don't agree with all of them.

> This is one of the reasons why I think links to the Crockford book
> should have a big warning label attached.

Seconded. This goes for all of the books that have been proposed for the
FAQ list.


- Conrad

Jorge

未読、
2008/10/11 17:04:112008/10/11
To:

Declare an outer function, including any necessary parameters and
data. Declare an inner function. Have the outer function return the
inner function.

function outer([params]) {
// vars declared here
var closure = function([params]) { /* code here */ }

return closure;
}

Or, manage somehow to keep a reference to the inner function, one that
will last after the outer function has returned, as in:

var refSaver;

function outer([params]) {
// vars declared here
refSaver = function([params]) { /* code here */ }
}

Or:

function outer([params]) {
// vars declared here
window.onresize = function([params]) { /* code here */ }
}

--
Jorge.

Jorge

未読、
2008/10/11 17:21:582008/10/11
To:
On Oct 10, 5:38 pm, MartinRineh...@gmail.com wrote:

"The execution context contains names and values of, among others,
variables, parameters and inner functions. When outer() returns a
function it also returns its execution context at the time of the
return."

The idea is something like:

0.- Upon entering a function, a new execution context is created for
it.
1.- The execution context of outer functions is accessible from within
any inner functions.
2.- When an outer function returns its current execution context is
destroyed unless reference(s) to inner function(s) survive.
3.- In that event, the execution context of the outer function can't
be destroyed until all the references to inner functions that have
access to it are destroyed as well.

--
Jorge.

Jorge

未読、
2008/10/11 17:32:292008/10/11
To:
On Oct 10, 5:38 pm, MartinRineh...@gmail.com wrote:

"Some authors said (and this was where I got confused) that the
closure has access to the variables of the outer function. This is
sort of true. Really it has access to the variable's names and values
at the moment the closure is created."

This isn't clear enough... a bit messy.

An inner function that survives keeps working **exactly*as*it*did**
before outer() returned. That's all. I'm not sure what do you mean
with "Really it has access to the variable's names and values at the
moment the closure is created" ? There's not any kind of 'memory
effect' nor nothing like that...

--
Jorge.

Lasse Reichstein Nielsen

未読、
2008/10/11 18:13:092008/10/11
To:
Jorge <jo...@jorgechamorro.com> writes:

> On Oct 10, 5:38 pm, MartinRineh...@gmail.com wrote:

> "Some authors said (and this was where I got confused) that the
> closure has access to the variables of the outer function. This is
> sort of true. Really it has access to the variable's names and values
> at the moment the closure is created."
>
> This isn't clear enough... a bit messy.

It's also wrong. The closure has access to the actual variables, not
just their value at the time the closure was created, including any
change to the variable, before or after the closure was created.T

That's why the following doesn't work as most people expect it to:

for (var i = 0; i < 10; i++) {
setTimeout(function(){alert(i);},i*2000);
}

It alerts "10" all ten times.

/L
--
Lasse Reichstein Holst Nielsen

Jorge

未読、
2008/10/11 18:17:222008/10/11
To:
On Oct 10, 5:38 pm, MartinRineh...@gmail.com wrote:
> I've rewritten a short article explaining closures in JavaScript.
> It's
>  at:
>
> http://www.martinrinehart.com/articles/javascript-closures.html
>

"Really it has access to the variable's names and values


at the moment the closure is created."

No 'memory effects': in this example there are 10 different inner
functions that survive after the outer (window.onload) function
returns. They are created at different times and at different values
of 'n'. But they all alert the same value: the value that n has in the
(left orphan by window.onload's return) execution context of the outer
function: 10.

See: http://jorgechamorro.com/cljs/020/

<script>
window.onload= function () {
var e, n;
for (n=0; n<10; n++) {
document.body.appendChild(
e= document.createElement('button'
)).innerHTML= n;
e.onclick= function () { alert(n) };
}
};
</script>

--
Jorge.

Jorge

未読、
2008/10/11 18:23:582008/10/11
To:
On Oct 12, 12:13 am, Lasse Reichstein Nielsen <lrn.unr...@gmail.com>
wrote:
> (...)

> That's why the following doesn't work as most people expect it to:
>
>  for (var i = 0; i < 10; i++) {
>    setTimeout(function(){alert(i);},i*2000);
>  }
>
> It alerts "10" all ten times.


On Oct 12, 12:17 am, Jorge <jo...@jorgechamorro.com> wrote:
>
> (..) But they all alert the same value: the value that n has in the


> (left orphan by window.onload's return) execution context of the outer
> function: 10.
>

LOL :-)

--
Jorge.

Dr J R Stockton

未読、
2008/10/11 14:31:592008/10/11
To:
In comp.lang.javascript message <gcov6t$hcv$1...@registered.motzarella.org>
, Fri, 10 Oct 2008 18:23:40, dhtml <dhtmlk...@gmail.com> posted:

>D. Flanagan himself has said that the Pocket Reference was "probably
>out of date."
>http://groups.google.com/group/comp.lang.javascript/msg/0866b23771e3a75
>e?dmode=source

Any book user or buyer should check its publication date (the publisher
and the year should be added to the FAQ entries), and not expect it to
cover anything more recent.

Since most JavaScript is executed by an agent remote from the author, by
various browsers of various ages, an Internet author should be very wary
of using anything that is not in ISO/IEC 16262.

Pocket Flanagan 2, October 2002, should cover what is in ECMA 262.

For those Flanagans, the FAQ should link to index.html not toc.html;
index should link to toc.

John G Harris

未読、
2008/10/12 13:49:422008/10/12
To:
On Sat, 11 Oct 2008 at 22:58:32, in comp.lang.javascript, Conrad Lender
wrote:

>On 2008-10-11 21:31, John G Harris wrote:
>> Moreover, the language Crockford defines isn't JavaScript, or even
>> javascript. It's a language where you aren't allowed to do
>>
>> ... { ... { ... } ... } ...
>
>Where does he say that?

In the syntax diagrams.


>You're quoting him out of context; JSON wouldn't be possible if nested
>curlies weren't allowed.

Perhaps I should have said I wasn't talking about literals.


> Just a guess, but he was probably talking about
>the absence of (traditional*) block scope in JavaScript, and was
>suggesting that unnecessary {} blocks shouldn't be used, in order to
>avoid confusion. In that context, I would agree with Crockford.

He does say that a block is not a scope. What he doesn't say is that a
block is also a statement. Whether that's for doctrinaire reasons or
from ignorance I don't know.

I don't think he says in words that he doesn't want to nest blocks.
Perhaps he couldn't think of any way of discouraging people from doing

... { ... if (true) { ... } ... } ...


John
--
John Harris

Peter Michaux

未読、
2008/10/12 14:41:032008/10/12
To:
On Oct 10, 8:44 am, David Mark <dmark.cins...@gmail.com> wrote:
> On Oct 10, 11:38 am, MartinRineh...@gmail.com wrote:
>
> > I've rewritten a short article explaining closures in JavaScript.
> > It's
> >  at:
>
> >http://www.martinrinehart.com/articles/javascript-closures.html
>
> It gets off to a dubious start:
>
> "I had the best books (Flanagan, Resig, Crockford)"
>
> Flanagan has been proven clueless

I think "clueless" is incorrect and inappropriate. He knows a lot as
displayed many times in his book and I still find his book a useful
starting resource for most browser-related issues. Yes his book has
mistakes but that does not make him clueless.

Peter

Peter Michaux

未読、
2008/10/12 14:42:562008/10/12
To:
On Oct 10, 10:06 am, MartinRineh...@gmail.com wrote:
> David Mark wrote:
> > "I had the best books (Flanagan, Resig, Crockford)"
>
> > Flanagan has been proven clueless and Resig's books belong in the
> > comedy racks (or on a bonfire.)
>
> > And there isn't much there.  This is a far superior article:
>
> >http://www.jibbering.com/faq/faq_notes/closures.html
>
> Flanagan is listed in the FAQ as the best JavaScript book.

"best" is a comparative term.

The jibbering article is a good resource.

Peter

Conrad Lender

未読、
2008/10/12 14:54:412008/10/12
To:
On 2008-10-12 19:49, John G Harris wrote:
>>> Moreover, the language Crockford defines isn't JavaScript, or even
>>> javascript. It's a language where you aren't allowed to do
>>>
>>> ... { ... { ... } ... } ...
>>
>>Where does he say that?
>
> In the syntax diagrams.

OK, I see what you mean. This is on the same page where he writes that
"if(expression)" can only be followed by a block. The grammar he's
defining here is not that of javascript, but of the subset he calls the
Good Parts. That's the whole point of the book - dividing the language
into good and bad (and, in the appendix, awful) parts. I think most
people who work with any language for a while instinctively do the same
thing in their minds, and Crockford wrote a book about it. As I said,
it's not a tutorial, but a collection of opinions.

> I don't think he says in words that he doesn't want to nest blocks.
> Perhaps he couldn't think of any way of discouraging people from doing
>
> ... { ... if (true) { ... } ... } ...

Off the top of my head I can't think of a single reason to use a block
unless it's necessary (except following if/else/for/while/etc, which is
a question of coding style) so I think that excluding them from the Good
Parts was the correct choice. "if (true) {...}" doesn't make any sense
at all.
For the record, I do disagree on quite a number of other suggestions and
opinions in the book, but that hardly made it worthless for me.


- Conrad

David Mark

未読、
2008/10/12 22:15:012008/10/12
To:
On Oct 12, 2:41 pm, Peter Michaux <petermich...@gmail.com> wrote:
> On Oct 10, 8:44 am, David Mark <dmark.cins...@gmail.com> wrote:
>
> > On Oct 10, 11:38 am, MartinRineh...@gmail.com wrote:
>
> > > I've rewritten a short article explaining closures in JavaScript.
> > > It's
> > >  at:
>
> > >http://www.martinrinehart.com/articles/javascript-closures.html
>
> > It gets off to a dubious start:
>
> > "I had the best books (Flanagan, Resig, Crockford)"
>
> > Flanagan has been proven clueless
>
> I think "clueless" is incorrect and inappropriate. He knows a lot as

His name has come up here a lot over the years. It seems to me that
most of it was bad. I certainly wouldn't recommend buying his books.
He's no Resig when it comes to cluelessness. I'll leave it at that.

Peter Michaux

未読、
2008/10/12 22:50:262008/10/12
To:
On Oct 12, 7:15 pm, David Mark <dmark.cins...@gmail.com> wrote:
> On Oct 12, 2:41 pm, Peter Michaux <petermich...@gmail.com> wrote:
>
>
>
> > On Oct 10, 8:44 am, David Mark <dmark.cins...@gmail.com> wrote:
>
> > > On Oct 10, 11:38 am, MartinRineh...@gmail.com wrote:
>
> > > > I've rewritten a short article explaining closures in JavaScript.
> > > > It's
> > > >  at:
>
> > > >http://www.martinrinehart.com/articles/javascript-closures.html
>
> > > It gets off to a dubious start:
>
> > > "I had the best books (Flanagan, Resig, Crockford)"
>
> > > Flanagan has been proven clueless
>
> > I think "clueless" is incorrect and inappropriate. He knows a lot as
>
> His name has come up here a lot over the years.  It seems to me that
> most of it was bad.

People seem to like to point out the mistakes because that is actually
useful. It would be boring and pointless to read about all the he
wrote that are correct.


> I certainly wouldn't recommend buying his books.

That is a different story. I would recommend his book but would warn
that there are errors both small and large. I think a beginner is best
served by a paper book that covers the language and the DOM.
Flanagan's book fits that bill best of the options available. It isn't
so good to say to a beginner, "hey there are some documents on there
and there on the web. Try the terse specs and the Mozilla site and the
archives of c.l.js are good but there is a lot of pedantic arguing to
wade through. Just jump in the deep end with the sharks." Flangan's
book is a much more gentle introduction.

Peter

sasuke

未読、
2008/10/13 13:14:302008/10/13
To:
On Oct 10, 9:07 pm, Lasse Reichstein Nielsen <lrn.unr...@gmail.com>
wrote:
>
> [snip]
>
> A closure is a piece of code together with a binding of values to the
> free variables of that code.
>
> A free variable is one that occur in the code, but is not declared
> there.

So does it mean that even global variables in Javascript are `free
variables' given the fact that they can be used without being declared
or is it that the definition is a loose one?

Also, given the function:

---------------------------------->B--------------------------
function attachEvents() {
var divs = document.getElementsByTagName("DIV");
if(!divs) return;
for(var i = 0, maxI = divs.length; i < maxI; ++i) {
var d = divs[i];
d.onclick = function() {
// some complicated processing with a lot of variables
alert("Hello from " + d.id);
}
}
}
window.onload = function() {
attachEvents();
// something complicated
attachEvents();
}
---------------------------------->B--------------------------

Will the second invocation of the function `attachEvents' make the
execution context of the first run along with the previously created
function objects eligible for garbage collection or do they need to be
explicitly grounded [set to null]?

/sasuke

Lasse Reichstein Nielsen

未読、
2008/10/13 14:55:202008/10/13
To:
sasuke <datab...@gmail.com> writes:

> On Oct 10, 9:07 pm, Lasse Reichstein Nielsen <lrn.unr...@gmail.com>
> wrote:
>>
>> [snip]
>>
>> A closure is a piece of code together with a binding of values to the
>> free variables of that code.
>>
>> A free variable is one that occur in the code, but is not declared
>> there.
>
> So does it mean that even global variables in Javascript are `free
> variables' given the fact that they can be used without being declared
> or is it that the definition is a loose one?

I variable is not inherently free or not. A variable occurence in a
part of a program, e.g., function declaration, is free in that
function if the function doesn't contain a declaration of that variable.

Example:

function foo(x) {
return function(y) {
alert(x+y);
}
}

This entire function has only one free variable: "alert".
The variable occurences "x" and "y" are bound by the argument
declarations of the surrounding functions.

The inner function:
function(y) { alert(x+y); }
has two free variables: "alert" and "x".

Notice that the same occurence of "x" can be both free and bound
depending on the scope one consider.


> Also, given the function:
>
> ---------------------------------->B--------------------------
> function attachEvents() {
> var divs = document.getElementsByTagName("DIV");
> if(!divs) return;
> for(var i = 0, maxI = divs.length; i < maxI; ++i) {
> var d = divs[i];
> d.onclick = function() {
> // some complicated processing with a lot of variables
> alert("Hello from " + d.id);
> }
> }
> }
> window.onload = function() {
> attachEvents();
> // something complicated
> attachEvents();
> }
> ---------------------------------->B--------------------------
>
> Will the second invocation of the function `attachEvents' make the
> execution context of the first run along with the previously created
> function objects eligible for garbage collection or do they need to be
> explicitly grounded [set to null]?

That depends entirely on the javascript implementation.

Best case, nothing remains and the garbage collector claims it all.

Worst case, the garbage collector barfs on the DOM->JS function->DOM
dependencies and collects nothing. That's a memory leak. I believe
IE 6 might do just that.

David Mark

未読、
2008/10/13 14:56:322008/10/13
To:
On Oct 13, 1:14 pm, sasuke <database...@gmail.com> wrote:
> On Oct 10, 9:07 pm, Lasse Reichstein Nielsen <lrn.unr...@gmail.com>
> wrote:
>
>
>
> > [snip]
>
> > A closure is a piece of code together with a binding of values to the
> > free variables of that code.
>
> > A free variable is one that occur in the code, but is not declared
> > there.
>
> So does it mean that even global variables in Javascript are `free
> variables' given the fact that they can be used without being declared
> or is it that the definition is a loose one?

The term "free variable" (as defined here) could be used to describe
global variables that are referenced within functions. Regardless,
global variables are not part of the binding described in the closure
definition.

>
> Also, given the function:
>
> ---------------------------------->B--------------------------
> function attachEvents() {
>   var divs = document.getElementsByTagName("DIV");

Inefficient. Use the collection itself.

>   if(!divs) return;

You don't need to do that with gEBTN.

>   for(var i = 0, maxI = divs.length; i < maxI; ++i) {

Inefficient. Use a while that counts down to 0.

>     var d = divs[i];
>     d.onclick = function() {
>       // some complicated processing with a lot of variables
>       alert("Hello from " + d.id);
>     }
>   }}

You are leaking memory. Every one of these creates this chain:

[DOM element X] ---onclick---> [anon function] ---> [variable object]
---> [DOM element A]

You forgot to set divs to null too. Same issue.

Unfortunately, your design doesn't allow you to set d to null.

function attachEvents() {
var el, index = document.getElementsByTagName('div').length;
while (index--) {
el = document.getElementsByTagName('div')[index];
el.onclick = (function(id) {
return function() { alert('Hello from ' + id); };
})(el.id);
}
el = null;
}

Or better yet, attach one listener and use delegation.

David Mark

未読、
2008/10/13 14:59:262008/10/13
To:
On Oct 13, 2:56 pm, David Mark <dmark.cins...@gmail.com> wrote:
> On Oct 13, 1:14 pm, sasuke <database...@gmail.com> wrote:
>
[snip]
> ---> [DOM element A]

Typo. Should be X of course (not A.) The whole point is that it is a
circular reference.

Conrad Lender

未読、
2008/10/14 7:16:592008/10/14
To:
[second attempt; the first didn't show up for some reason]

On 2008-10-13 20:56, David Mark wrote:
> On Oct 13, 1:14 pm, sasuke <database...@gmail.com> wrote:
>> function attachEvents() {
>> var divs = document.getElementsByTagName("DIV");
>
> Inefficient. Use the collection itself.

(see below)

>> for(var i = 0, maxI = divs.length; i < maxI; ++i) {
>
> Inefficient. Use a while that counts down to 0.

(That's micro-optimization, unlikely to produce any measurable
performance gains. It also inverts the order of element processing,
which may be significant in some cases.)

> function attachEvents() {
> var el, index = document.getElementsByTagName('div').length;
> while (index--) {
> el = document.getElementsByTagName('div')[index];

Are you suggesting that calling getElementsByTagName() in a loop is more
efficient than storing a reference to the collection in a variable, and
using the variable in the loop? I doubt that, and some preliminary
testing shows that your recommendation is consistently slower than
sasuke's; in some implementations (Opera, Safari) even by a factor of 4.


- Conrad

Jorge

未読、
2008/10/14 10:00:482008/10/14
To:
On Oct 13, 8:56 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
> function attachEvents() {
>   var el, index = document.getElementsByTagName('div').length;
>   while (index--) {
>      el = document.getElementsByTagName('div')[index];
>      el.onclick = (function(id) {
>         return function() { alert('Hello from ' + id); };
>      })(el.id);
>   }
>   el = null;
>
> }


function attachEvents () {
var divs= document.getElementsByTagName('div'),
f= function (event) { alert(this.id) },
index= divs.length;

while (index--) { divs[index].onclick= f }
}

--
Jorge.

David Mark

未読、
2008/10/14 17:42:502008/10/14
To:
On Oct 14, 7:16 am, Conrad Lender <crlen...@yahoo.com> wrote:
> [second attempt; the first didn't show up for some reason]
>
> On 2008-10-13 20:56, David Mark wrote:
>
> > On Oct 13, 1:14 pm, sasuke <database...@gmail.com> wrote:
> >> function attachEvents() {
> >>   var divs = document.getElementsByTagName("DIV");
>
> > Inefficient.  Use the collection itself.
>
> (see below)
>
> >>   for(var i = 0, maxI = divs.length; i < maxI; ++i) {
>
> > Inefficient.  Use a while that counts down to 0.
>
> (That's micro-optimization, unlikely to produce any measurable
> performance gains. It also inverts the order of element processing,
> which may be significant in some cases.)

But not in this case.

>
> > function attachEvents() {
> >   var el, index = document.getElementsByTagName('div').length;
> >   while (index--) {
> >      el = document.getElementsByTagName('div')[index];
>
> Are you suggesting that calling getElementsByTagName() in a loop is more
> efficient than storing a reference to the collection in a variable, and

Yes. Browsers optimize for that pattern.

> using the variable in the loop? I doubt that, and some preliminary

Doubt it all you want.

> testing shows that your recommendation is consistently slower than
> sasuke's; in some implementations (Opera, Safari) even by a factor of 4.

Nonsense. Opera has a long article on their site about this.

David Mark

未読、
2008/10/14 17:44:542008/10/14
To:

It is pointless to rewrite this pattern (diminishing returns.) A
single listener should be used.

David Mark

未読、
2008/10/14 18:06:162008/10/14
To:

Trying to find that article, but nothing that exactly matches on the
Opera site. Maybe I am thinking of something else. Regardless, the
while loop is definitely faster in all implementations (no need to
test that) and closures/memory leaks are the issue at hand.

As I mentioned, the best solution is to attach one listener and get
the id from the event target. All of these other loopy patterns
(closures or not) are silly.

David Mark

未読、
2008/10/14 18:29:192008/10/14
To:
On Oct 14, 10:00 am, Jorge <jo...@jorgechamorro.com> wrote:

Oops, forgot to mention that this will leak memory in IE.

[divs]->[DOM node]->[f]->[variable object]->[divs]

Add divs = null to break the chain at the end (of course.)

See the link posted previously.


Lasse Reichstein Nielsen

未読、
2008/10/14 18:32:032008/10/14
To:
David Mark <dmark....@gmail.com> writes:

> On Oct 14, 7:16 am, Conrad Lender <crlen...@yahoo.com> wrote:
>> [second attempt; the first didn't show up for some reason]
>>
>> On 2008-10-13 20:56, David Mark wrote:

>> > function attachEvents() {
>> >   var el, index = document.getElementsByTagName('div').length;
>> >   while (index--) {
>> >      el = document.getElementsByTagName('div')[index];
>>
>> Are you suggesting that calling getElementsByTagName() in a loop is more
>> efficient than storing a reference to the collection in a variable, and
>
> Yes. Browsers optimize for that pattern.

Do you have any references for that? It sounds likely that they do
something smart, but I find it unlikely that it will be faster
to call a function to return the same value again than just looking
it up in a local variable.

> Nonsense. Opera has a long article on their site about this.

Link?

David Mark

未読、
2008/10/14 18:47:592008/10/14
To:
On Oct 14, 6:32 pm, Lasse Reichstein Nielsen <lrn.unr...@gmail.com>
wrote:

> David Mark <dmark.cins...@gmail.com> writes:
> > On Oct 14, 7:16 am, Conrad Lender <crlen...@yahoo.com> wrote:
> >> [second attempt; the first didn't show up for some reason]
>
> >> On 2008-10-13 20:56, David Mark wrote:
> >> > function attachEvents() {
> >> >   var el, index = document.getElementsByTagName('div').length;
> >> >   while (index--) {
> >> >      el = document.getElementsByTagName('div')[index];
>
> >> Are you suggesting that calling getElementsByTagName() in a loop is more
> >> efficient than storing a reference to the collection in a variable, and
>
> > Yes.  Browsers optimize for that pattern.
>
> Do you have any references for that? It sounds likely that they do

I have been trying to dig it up myself.

> something smart, but I find it unlikely that it will be faster

Thanks for that, but it is possible that I did something dumb in this
case. The fact that I can't find the article is not encouraging.

> to call a function to return the same value again than just looking
> it up in a local variable.

Well, define looking it up in a local variable when the local variable
is a reference to a live nodelist? I can't as I don't write browsers.

>
> > Nonsense.  Opera has a long article on their site about this.
>
> Link?

Not on Opera from what I can see.

Conrad Lender

未読、
2008/10/14 18:54:272008/10/14
To:
On 2008-10-14 23:42, David Mark wrote:
>> > function attachEvents() {
>> > var el, index = document.getElementsByTagName('div').length;
>> > while (index--) {
>> > el = document.getElementsByTagName('div')[index];
>>
>> Are you suggesting that calling getElementsByTagName() in a loop is more
>> efficient than storing a reference to the collection in a variable, and
>
> Yes. Browsers optimize for that pattern.

I would also like to see a source for that.

>> using the variable in the loop? I doubt that, and some preliminary
>
> Doubt it all you want.
>
>> testing shows that your recommendation is consistently slower than
>> sasuke's; in some implementations (Opera, Safari) even by a factor of 4.
>
> Nonsense. Opera has a long article on their site about this.

Well. Here I am, having tested this in 5 current browsers (not
comprehensive, yes, but as I said, they were preliminary tests), and
here you are saying "nonsense". Is that all you've got?


- Conrad

David Mark

未読、
2008/10/14 18:57:212008/10/14
To:
On Oct 14, 6:54 pm, Conrad Lender <crlen...@yahoo.com> wrote:
> On 2008-10-14 23:42, David Mark wrote:
>
> >> > function attachEvents() {
> >> >   var el, index = document.getElementsByTagName('div').length;
> >> >   while (index--) {
> >> >      el = document.getElementsByTagName('div')[index];
>
> >> Are you suggesting that calling getElementsByTagName() in a loop is more
> >> efficient than storing a reference to the collection in a variable, and
>
> > Yes.  Browsers optimize for that pattern.
>
> I would also like to see a source for that.
>
> >> using the variable in the loop? I doubt that, and some preliminary
>
> > Doubt it all you want.
>
> >> testing shows that your recommendation is consistently slower than
> >> sasuke's; in some implementations (Opera, Safari) even by a factor of 4.
>
> > Nonsense.  Opera has a long article on their site about this.
>
> Well. Here I am, having tested this in 5 current browsers (not

Yes, there you are. Your testing has been previously proven suspect.
Pardon me if I am non-responsive.

RobG

未読、
2008/10/14 20:49:202008/10/14
To:
On Oct 11, 1:38 am, MartinRineh...@gmail.com wrote:
> I've rewritten a short article explaining closures in JavaScript.
> It's
> at:
>
> http://www.martinrinehart.com/articles/javascript-closures.html
>
> A big Thank You to PointedEars and Jorge for helping me get closer to
> the truth.

Seems the article hasn't been updated since you started this thread,
are you going to?

Don't be discouraged by criticism, teaching something is a very good
way to learn it thoroughly if you are prepared to learn yourself from
the experience.

A couple of tips, some mentioned by others, some not:

1. Closures are a feature of ECMAScript. Javascript is not a subset
of ECMAScript, quite the opposite, so I'd remove the note below the
title. Crockford’s book is just his opinion on some features of the
language that he considers good/bad/ugly, I don’t think it’s a serious
attempt to modify the standard (although I haven’t read it).

2. The article’s definition of a closure is meaningless to me, but
then again, I haven’t read a one-line description that makes sense. To
me a closure is the ability to keep a reference to a function variable
after the function has finished executing. That isn’t particularly
accurate from a technical viewpoint, but it does the job for me.

3. In the “Why do you want closures” section, the statement “...the
closure is invisible except to the singe public function of the
closure” is misleading: any number of functions can have closures to
the variables of a function. Also, if the functions that have those
references are public, they can be called privileged (see Crockford’s
article on public and private members in javascript[1]). A reference
to that article should be included.

4. A closure is a consequence of declaring one function inside another
using either a formal declaration, function expression or statement.
It’s only useful if some reference is kept of course, but the closure
isn’t the variable reference, it’s the ability of the “inner” function
to access the activation object of the outer function and its
variables.

I think you should reference the FAQ article[2] which is not only a
comprehensive and technically excellent article on closures, it
teaches an awful lot about the fundamentals of functions in general.

1. Douglas Crockford, Private Members in JavaScript :
<URL: http://javascript.crockford.com/private.html>

2. Richard Cornford, et al, Javascript Closures
<URL: http://www.jibbering.com/faq/faq_notes/closures.html >

--
Rob

新着メール 0 件