JavaScript is a more powerful ProgrammingLanguage than many people give it credit for. After being intrigued by BlocksInRuby, I decided to try my hand at implementing blocks, LexicalClosure''''''s, HigherOrderFunction''''''s, and AnonymousFunction''''''s in JavaScript. JavaScript functions are FirstClassFunction''''''s in that they are objects which can be easily passed around, thereby enabling a FunctionalProgramming style, if desired. AnonymousFunction''''''s or LambdaExpression''''''s can be created either with the ''function'' keyword or the ''Function'' constructor. The Function constructor allows you to define the body of the function dynamically. For illustration, I have taken a few examples from the on-line version of ''ProgrammingRuby'' (the PickAxeBook) and transformed them into JavaScript. Already knowing PythonLanguage helped me make the transition to JavaScript. //////////////////////////////////////// // handy functions to help with browser output function dwrb(thing) { if (arguments.length == 1) document.writeln(thing + '
'); else document.writeln('
'); } function dwrs(thing) { if (arguments.length == 1) document.writeln(thing + ' '); else document.writeln(' '); } //////////////////////////////////////// function fibUpTo(max, block) { var i1=1, i2=1; while (i1 <= max) { block(i1); var tmp2 = i2; i2 = i1 + i2; i1 = tmp2; } } fibUpTo(1000, dwrs); dwrb(); // produces 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 // LexicalClosure function into(anArray) { return function(val) { anArray[anArray.length] = val; } } var a = ['foo', 'bar']; fibUpTo(20, into(a)); dwrb(a); // produces foo,bar,1,1,2,3,5,8,13 //////////////////////////////////////// // HigherOrderFunction added to built-in Array type Array.prototype.find = function(block) { for (var i=0; i 30; })); // produces null dwrs(arr.find(function(v) { return v*v > 30; })); // produces 7 dwrb(arr.find(function(v) { return v*v*v > 30; })); // produces 5 //////////////////////////////////////// // HigherOrderFunction''''''s added to built-in Array type Array.prototype.inject = function(n, block) { for (var i=0; i -1) calc = new Function('n', funcbody('*')); else calc = new Function('n', funcbody('+')); var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; dwrb(arr.collect(calc)); // might produce 4,8,12,16,20,24,28,32,36,40 } } The above examples are known to work in MozillaFirefox, SafariBrowser, InternetExplorer 5.2, and ancient NetscapeNavigator 4.75. If your IE is >= 5.5, you can use the Array.push method in the "into" and "collect" functions. -- ElizabethWiethoff ---- Beware of circular references in closures when targeting InternetExplorer. If a DOM object is involved it will produce a memory leak due to the bizarre JavaScript interpreter design. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp ---- JavaScript Array objects in MozillaFirefox 1.5 will implement some new methods: every(), some(), forEach(), filter(), and map(). Each of these Array methods takes as its parameter a function of the form function func_name(value, index, array) { // code goes here } If you don't use Firefox, you can simulate its new Array.filter method, for example, by adding a function to the Array prototype: if (!Array.filter) { // HigherOrderFunction added to built-in Array type Array.prototype.filter = function(predicate) { var a = []; for (var i=0; i 90; } var aNumbers = [56, 43, 23, 94, 32, 91]; var aOver90Numbers = aNumbers.filter(isOver90); document.write("The numbers over 90 are " + aOver90Numbers + "
"); Mozilla's new Array.filter method (and the others) can also take an optional second parameter, which I have not shown here. See http://www.webreference.com/programming/javascript/ncz/column4/ and http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array -- ElizabethWiethoff ---- This article illustrates more uses of higher order functions in JavaScript: * http://w3future.com/html/stories/hop.xml ---- See also JavaScriptRocks, BlocksInManyLanguages ---- CategoryJavaScript CategoryClosure