Listing 7. Functional Programming Style
Copy the codeThe code is as follows:
// Modify the previous code
function factorial(n){
if (n == 1){
return 1;
} else {
return factorial(n - 1) * n;
}
}
// Code closer to "functional" programming style
function factorial(n){
if (equal(n, 1)){
return 1;
} else {
return mul(n, factorial(dec(n)));
}
}
Closures and their use
Closures are an interesting topic. When another function inner is defined inside one function outer, which references variables within the scope of the outr and uses inner functions outside the outr, a closure is formed. Although it is more complicated to describe, it often uses closure features in actual programming.
Listing 8. An example of a closure
Copy the codeThe code is as follows:
function outter(){
var n = 0;
return
function (){
return n++;
}
}
var o1 = outter();
o1();//n == 0
o1();//n == 1
o1();//n == 2
var o2 = outter();
o2();//n == 0
o2();//n == 1
The anonymous function function(){return n++;} contains a reference to the local variable n of the outter. Therefore, when the outter returns, the value of n is retained (it will not be recycled by the garbage collection mechanism). Continuously calling o1() will change the value of n. The value of o2 does not change as o1() is called. The first time you call o2 will get the result of n==0. In object-oriented terms, o1 and o2 are different instances and do not interfere with each other.
Overall, closures are simple, isn't they? However, closures can bring many benefits, such as what we often use in web development:
Listing 9. Closures in jQuery
Copy the codeThe code is as follows:
var con = $("div#con");
setTimeout( function (){
({background:"gray"});
}, 2000);
The above code uses the selector of jQuery, finds the div element with id con, registers the timer, and after two seconds, sets the background color of the div to gray. The magic of this code snippet is that after calling the setTimeout function, the con is still maintained inside the function. After two seconds, the background color of the div element with id is con indeed changed. It should be noted that setTimeout has been returned after the call, but con is not released because con refers to the variable con in the global scope.
Using closures can make our code more concise, and a more detailed discussion of closures can be found in the reference information. Due to the particularity of closures, you must be careful when using closures. Let’s take a look at an example that is easy to confusing:
Listing 10. Incorrect use of closures
Copy the codeThe code is as follows:
var outter = [];
function clouseTest () {
var array = ["one", "two", "three", "four"];
for ( var i = 0; i < ;i++){
var x = {};
= i;
= array[i];
= function (){
print(i);
}
(x);
}
}
The above code snippet is very simple, store multiple such JavaScript objects into an outter array:
Listing 11. Anonymous Objects
Copy the codeThe code is as follows:
{
no : Number,
text : String,
invoke : function (){
// Print your own no field
}
}
Let's run this code:
Listing 12. Error results
Copy the codeThe code is as follows:
closeTest();// Call this function to add objects to the outter array
for ( var i = 0, len = ; i < len; i++){
outter[i].invoke();
}
Surprisingly, this code will print:
4
4
4
4
Instead of sequences like 1, 2, 3, 4. Let's see what's going on. Each internal variable x fills out its own no,text,invoke field, but invoke always prints the last i. It turns out that the function we registered for invoke is:
Listing 13. Causes of the error
Copy the codeThe code is as follows:
function invoke(){
print(i);
}
This is true for every invoke. When outter[i].invoke is called, the value of i will be reached. Since i is a local variable in the closure, the value when the for loop finally exits is 4, so each element in the call to outter will get 4. Therefore, we need to make some modifications to this function:
Listing 14. Use closures correctly
Copy the codeThe code is as follows:
var outter = [];
function clouseTest2(){
var array = ["one", "two", "three", "four"];
for ( var i = 0; i < ;i++){
var x = {};
= i;
= array[i];
= function (no){
return
function (){
print(no);
}
}(i);
(x);
}
}
By curling the function, we register this function for each element of the outter this time:
Copy the codeThe code is as follows:
//x == 0
= function (){print(0);}
//x == 1
= function (){print(1);}
//x == 2
= function (){print(2);}
//x == 3
= function (){print(3);}
In this way, you can get the correct result.
Examples in practical applications
OK, there is enough theoretical knowledge. Let’s take a look at JavaScript functional programming in the real world. There are many people who have made a lot of efforts to make JavaScript an object-oriented style (JavaScript itself is programmable). In fact, object-oriented is not necessary. Using functional programming or a mixture of the two can make the code more beautiful and concise.
jQuery is a very excellent JavaScript/Ajax framework, small, flexible, with plug-in mechanism. In fact, jQuery has a very rich plug-in, from expression verification, client image processing, UI, animation, etc. And the biggest feature of jQuery, as it claims, has changed the style of people writing JavaScript code.
Elegant jQuery
Experienced front-end development engineers will find that the most common work has a certain pattern: select some DOM elements and then apply some rules to these elements, such as modifying style sheets, registering event processors, etc. So jQuery implements the perfect CSS selector and provides cross-browser support:
Previous page123Next pageRead the full text