...

View Full Version : [RFI] Closures - real world use



liorean
02-02-2004, 09:32 PM
I'm writing an article about closures in JavaScript. Does any of the coding genii here know some real-worldly examples that I can include, besides the obvious use of closures to store private members of objects, which I already have as an example?


(Alex Vincent, JKD, GlennGV, Jeff Mott, Beetle, Brothercake, Whammy and anyone I might have overlooked - I'm calling out to you here!)

RadarBob
02-03-2004, 03:11 AM
what the heck are closures?

Antoniohawk
02-03-2004, 03:24 AM
I second that Radar.

glenngv
02-03-2004, 04:52 AM
Originally posted by RadarBob
what the heck are closures?

http://en.wikipedia.org/wiki/Closure_(programming)
http://www.crockford.com/javascript/private.html
http://www.cabezal.com/blog/archives/000607.shtml
http://www.litotes.demon.co.uk/js_info/private_static.html

Nice article with practical application:
http://w3future.com/html/stories/callbacks.xml

Garadon
02-03-2004, 07:20 AM
wouldn't the

[array].sort().
setTimeOut
setInterval


be ehh closures?

liorean
02-03-2004, 09:18 AM
And from the first two replies to this post I bet you understand why this article is sorely needed...

Glenn: I personally think the HOP article has a better practical example, but in the end I didn't want to steal his. Do you have any ideas, expecially for template functions / function constructors? (I already have the object orientation-private members and the object binding for this and arguments as practical examples.)

RadarBob
02-03-2004, 01:10 PM
I still don't fully grock it; but inner classes in Java sounds like the same thing, so maybe it's not rocket surgery.

If I understand correctly, closures may solve a practical problem - that of namespace....

I love creating objects when I create javascript code. The object incapsulates it's own "global" variables nicely. BUT conventional JS object coding does not not solve the namespace problem for an object's functions. Function names are exposed to the HTML page in which it is included (or in-lined). And in particular I'd like to create utility functions that have the same name, for all my objects - printing out an objects properties for example. I guess you'd call this pseudo-overloading.

re: crockford.com link
For discussion's sake, not nitpicking...

I think what he's calling "private members" are just local scope variables. This is how one get's namespace protection for an object's properties (members as he calls them).

What he calls "priveleged methods" are simply the conventional way an object's methods are defined. His example "in-lines" the actual function code so to speak, but that's just a variation on a theme. The function's name is publicly exposed (a-la Janet Jackson), which is a problem one MUST solve to reach JavaScript reuseabilty nervana.


bottom lines
I did not know one could define a function w/in a function in JavaScript. Verwy Interwesting you wasskully wabbit!

I always knew that a function is "just another object" in Javascript but I did not appreciate the implications- this closure stuff exploits it's potential.

I was just staring blankly at http://en.wikipedia.org/wiki/Closure_(programming) If one speaks English, closures probably is no Einsteinian leap. Illustrating a feature using the same way of writing that one uses to formally define a language is no way to teach it.

RadarBob
02-03-2004, 04:10 PM
OK, want to read something understandable?

JavaScript the Definitive Guide fourth edition, page 173.

liorean
02-03-2004, 06:10 PM
Originally posted by RadarBob
I still don't fully grock it; but inner classes in Java sounds like the same thing, so maybe it's not rocket surgery.They address the same issues, yes.
If I understand correctly, closures may solve a practical problem - that of namespace....Could you explain what you mean by the practical problem of namespace? The word "namespace" has several rather different meanings depending on what programming environment you come from.
I love creating objects when I create javascript code. The object incapsulates it's own "global" variables nicely. BUT conventional JS object coding does not not solve the namespace problem for an object's functions. Function names are exposed to the HTML page in which it is included (or in-lined). And in particular I'd like to create utility functions that have the same name, for all my objects - printing out an objects properties for example. I guess you'd call this pseudo-overloading.Here JavaScript being functional at core comes into play. Functional languages traditionally doesn't do overloading, they do code forking.
re: crockford.com link
For discussion's sake, not nitpicking...

I think what he's calling "private members" are just local scope variables. This is how one get's namespace protection for an object's properties (members as he calls them).Again, in a functional language, objects are procedures, and all the object orientation of functional languages is traditionally constructed based on three principles: Lexical scoping, closure creation, and a structural base model (structural languages, in difference to procedural and imperative, limits flow control to code forking. There are no flow breaking statements in structural languages, and the functional paradigm builds on top of the structural.)
What he calls "priveleged methods" are simply the conventional way an object's methods are defined.Not really. You see, the functions HAVE to be declared in the constructor, because the constructor creates a closure. Again, this is how functional languages achieve object orientation.
His example "in-lines" the actual function code so to speak, but that's just a variation on a theme. The function's name is publicly exposed (a-la Janet Jackson), which is a problem one MUST solve to reach JavaScript reuseabilty nervana.The function name may be read, yes, because you can read out the source of the public method that contains it. However, there is no way to access it by that name, short of actually reading it out from source code.
bottom linesI did not know one could define a function w/in a function in JavaScript. Verwy Interwesting you wasskully wabbit!

I always knew that a function is "just another object" in Javascript but I did not appreciate the implications- this closure stuff exploits it's potential.Closures is one of the most powerful features coming out of the functional paradigm. JavaScript is more of a functional language than an imperative in terms of features, so I think this feature should be lifted forward.
I was just staring blankly at http://en.wikipedia.org/wiki/Closure_(programming) If one speaks English, closures probably is no Einsteinian leap. Illustrating a feature using the same way of writing that one uses to formally define a language is no way to teach it. That's not what he does. He gives a code sample in the language ML.

RadarBob
02-03-2004, 07:35 PM
Could you explain what you mean by the practical problem of namespace? The word "namespace" has several rather different meanings depending on what programming environment you come from.
If I have the following:


function UserDefinedObject () {
var myValue = null; //local scope only. Other code can use same variable name.

// methods
this.setValue = fetchIt;
}

function fetchIt() {
// fetchIt code here.
}


The name of the function, fetchIt in this case, must be unique in the page in which this code may be included.

As I understand it the following avoids the problem:


function UserDefinedObject () {
var myValue = null;

// methods
this.setValue = function () { //fetchIt code here};
}

Now the function is literally inside the object definition, just like myValue, and thus other code can have a setValue function that will not be ambiguous.

RadarBob
02-03-2004, 07:43 PM
Are the following two equivelent? Asked another way; what are the scope, inheretance, other(?) issues here?


function UserDefinedObject_one () {
// lots of good stuff
}

UserDefinedObject_one.prototype.setValue = function() {//set value code here};

VICE



function UserDefinedObject_two () {

function fetchIt () {
// set value code here
}
}

liorean
02-03-2004, 08:04 PM
No. JavaScript is lexically scoped, not dynamically scoped. That means that identifier names in a scope "shadows" identifiers in shallower (or lower, depending on terminology) scopes, and is in turned shadowed by identifiers in deeper (or higher) scopes. (ie variable names in a function scope are separate from variables in the global scope, and overrides the global variable when you use that identifier.)

An example:
var
x='ex';
function fn(x){
var
t='shallow: ('+x+');';
function fn(x){
var
t='deep: "'+x+'";';
return t;
}
return fn(t);
}
var
t='global: {'+x+'};';
fn(t); // => 'deep: "shallow: [global: {ex};];";'

liorean
02-03-2004, 08:48 PM
Ah, here's the deal: Each scope may only contain one object mapped to a certain identifier. The JavaScript parser will first do one parsing run of the code, compiling all functions, and declaring all variables (though NOT defining them). That means that functions will technically be declared and defined already, variables will only be declared. When finished it will go over the code again, this time executing it. This means that the last function with the given identifier will be the one that is defined. Variables will on the other hand not be defined until the definition is encountered in the execution run. This process is the same for functions, but note: It's done EACH TIME THE FUNCTION EXECUTES, not the single time the function is compiled. In a way, you can consider the global scope to be a closure you are operating within. That means that as long as you declare the function in a separate scope, you can use as many functions of that name as you wish.

A demonstration:
var
a=[];
function t(){
return false;
}
a.push(t);
var
t='global';
a.push(t);
function t(){
return true;
}
a.push(t);
t=function(){
return true;
};
a.push(t);
alert(a) // => function t(){return true;}, 'global', 'global', function (){return true;}Note the difference between the first and the last functions - one is named, the other is not.

glenngv
02-04-2004, 08:27 AM
Originally posted by liorean

Glenn: I personally think the HOP article has a better practical example, but in the end I didn't want to steal his. Do you have any ideas, expecially for template functions / function constructors? (I already have the object orientation-private members and the object binding for this and arguments as practical examples.)

I don't know if this is a good practical application of closures in javascript.

One of the main problems of combining multiple scripts from different authors is the onload conflict. Combining the onload handlers (without cancelling each other out) is the common problem facing newbie javascripters. By using functions as arguments and return values, you can easily fix the conflict.



function addWindowOnload(f){
var wo = window.onload;
return (wo) ? function(){wo();f()}:f;
}

function func1(){
alert('function 1');
}

function func2(msg){
alert(msg);
}

var func3 = new Function("alert('function 3')");
var func4 = function(){alert('function 4')}

window.onload = func1; //this type of assignment must be the first onload handler

//subsequent onload handlers
window.onload = addWindowOnload(function(){func2('function 2')});
window.onload = addWindowOnload(func3);
window.onload = addWindowOnload(func4);



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum