- The Book of Dojo
- Quick Installation
- Hello World
- Debugging Tutorial
- Introduction
- Part 1: Life With Dojo
- Part 2: Dijit
- Part 3: JavaScript With Dojo and Dijit
- Part 4: Testing, Tuning and Debugging
- Part 5: DojoX
- The Dojo Book, 0.4
Functions as Variables, or "Here, Do This."
Submitted by criecke on Sun, 04/29/2007 - 14:27.
Before jumping into the details, one aspect of Javascript requires some explanation. Unlike Java or C#, functions are first class objects in Javascript. You can do everything with a function that you can do with an integer, including:
- Assign it to a variable
- Use it as a value in an array, or associative array
- Pass it as a parameter
function applyMaxOrMin(a, b, fnName){
if(fnName == 'max'){
return Math.max(a,b);
}else{
return Math.min(a,b);
}
}
console.debug(applyMaxOrMin(1, 2, 'max'));
if(fnName == 'max'){
return Math.max(a,b);
}else{
return Math.min(a,b);
}
}
console.debug(applyMaxOrMin(1, 2, 'max'));
But you can make it a line or two shorter, and more general, by passing a function like this:
function applyTwoParameterFn(a, b, fn){
return fn(a,b);
}
console.debug(applyTwoParameterFn(1, 2, Math.max));
return fn(a,b);
}
console.debug(applyTwoParameterFn(1, 2, Math.max));
Interestingly, you can substitute any function that takes two numbers here, not just Max or Min.
"Ah," you might say, "that's like passing a class in Java and using reflection." Almost, but not quite. Java is still strict about type checking, even when calling functions through reflection. In our example, what if the function passed aren't compatible? In the example above, what if you pass a function with three variables? It's handled in The Javascript Way, i.e. sloppily. If the number of parameters doesn't quite fit, extra ones are lobbed off or null's are added to the end. Type conversion is applied like it should.
Note: There is no concept of overloading in Javascript! That's a fundamental difference between it and strongly-typed object languages like Java.
One special function type used a lot in dojo is the callback. Callbacks are functions that are supposed to be called when processing has ended. They are especially useful for asynchronous operations like XHR. You call an asynchronous function and say "call this function when you're done." If you've used event classes in Java, it's the same concept but looser.
In Java you can define classes anonymously, on-the-fly, right in the middle of a method call. You can do that in Javascript too. Simply define the function in the parameter list and omit the name. For example, instead of defining and passing a new function:
function myTwoParameterFn(a, b) {
return max(a, -b);
}
console.debug(myTwoParameterFn(1, 2, Math.max));
return max(a, -b);
}
console.debug(myTwoParameterFn(1, 2, Math.max));
We can shorten it to:
console.debug(myTwoParameterFn(
1, 2,
function(a,b){
return max(a, -b)
}
));
1, 2,
function(a,b){
return max(a, -b)
}
));
This makes from some pretty strange syntax, especially if the anonymous function is large. But callbacks are often specified this way when calling dojo functions.
- Printer-friendly version
- Login or register to post comments
- Subscribe post
mistake in sample
I think there is a mistake in the sample :
should be replace by:
Typo
"In our example, what if the function passed ~isn't~ compatible?"
Code written like Reflection should be considered Obfuscation
Dojo toolkit is a Public/OpenSource API (Really?!?). in the roadmap to 1.0 was the requirement to remove "Magical" code. Reflection is a shortcut that should seldom be used simple because it's nearly impossible to track down what exactly is happening under the hood. I've just spent 2 day writing REALLY in-depth trace code to see what should have been a simple 2-3 steps deep function call, but it wasn't. My project time line is now in jeopardy of being over budget. to whom ever posses the power to make this API more simple for the little guy: Please consider all reflection code to be a last resort!