JavaScript functional programming practices (from IBM) _ javascript skills

Source: Internet
Author: User
When it comes to functional programming, people often make the first impression of their academic school, which is obscure. It is probably the only programming method that is used by university professors who are undisciplined, unmasked, or even nervous. When it comes to functional programming, people often make the first impression of their academic school, which is obscure. It is probably the only programming method that is used by university professors who are undisciplined, unmasked, or even nervous.

Introduction to functional programming
When it comes to functional programming, people often make the first impression of their academic school, which is obscure. It is probably the only programming method that is used by university professors who are undisciplined, unmasked, or even nervous. This may be true at a certain stage in history, but function programming has played a huge role in practical applications recently, and more languages are constantly adding closures, to some extent, functional programming is gradually "assimilation" imperative programming.
The source of functional programming can be traced back to the 1930s S. The mathematician Alan Qiu Qi was conducting a research on the calculability of the problem, that is, the later lambda algorithm. Lambda calculus is essentially a function. A function can be used as an output or/or input of another function. When a series of functions are used, an expression chain is formed, this expression chain can finally obtain a value, and this process is the essence of computing.
However, this idea was difficult to implement on the basis of the hardware at that time. In history, we finally chose another mathematical theory parallel to the lambda theory of Qiu Qi: the Turing machine as the computing theory, and take another scientist Feng. noriman's computer structure was eventually implemented as hardware. Because the first computer is Feng. noriman's program storage structure, so the program running on this platform also inherits this gene, and programming languages such as C/Pascal depend to some extent on this system.
In 1950s, John McCarthy, a professor at MIT, went to Feng. lambda theory was successfully implemented on the machine of the noriman system and named it "LISt Processor". Now functional programming languages have become active in the computer science field.
Functional Programming Language Features
In functional programming languages, a function is the first type of object. That is to say, a function can exist independently without any other object. In object-oriented languages, functions (methods) are attached to objects and are part of objects. This j determines some special properties of a function in a functional language, such as an outgoing/incoming parameter and a common variable.
Unlike imperative programming languages, functional programming languages have some special concepts. We will discuss them separately:
Anonymous Functions
In functional programming languages, a function can have no name. An anonymous function usually indicates "a piece of code that can accomplish something ". This expression is useful in many cases, because we sometimes need to use a function to accomplish something, but this function may be temporary, there is no reason to generate a top-level function object. For example:

Listing 1. map Functions

function map(array, func){ var res = []; for ( var i = 0, len = array.length; i < len; i++){ res.push(func(array[i])); } return res; } var mapped = map([1, 3, 5, 7, 8], function (n){ return n = n + 1; }); print(mapped);

Running this code will print:
2, 4, 6, 8, 9 // Add 1 to each element in the array [1, 3, 5, 7, 8]


Note the call of the map function. The second parameter of map is a function. This function has an effect on each of the first parameters (arrays) of map, but it may have no significance for code other than map. Therefore, we do not need to define a function for it. Anonymous functions are enough.
Kerihua
Curialization converts a function that accepts multiple parameters into a function that accepts a single parameter (the first parameter of the initial function, and return the technology of the new function that accepts the remaining parameters and returns results. This sentence is a bit difficult. We can use examples to help you understand it:
List 2. colized Functions

function adder(num){ return function (x){ return num + x; } } var add5 = adder(5); var add6 = adder(6); print(add5(1)); print(add6(1));

Result:
6
7
Interestingly, the adder function accepts a parameter and returns a function, which can be called as expected. The variable add5 maintains the function returned by adder (5). This function can accept a parameter and return the sum of the parameter and 5.
Kerialization is very useful in DOM callback. We will see it in the following section.
High-order functions
High-order functions are further abstract functions. In fact, the map function we mentioned in the anonymous function section is a high-order function, which is available in many functional programming languages. The expression of map (array, func) indicates that the func function is applied to every element in the array and a new array is returned. Note that, map's implementation of array and func does not have any pre-assumptions, so it is called a "high-order" function:

Listing 3. High-Order Functions

function map(array, func){ var res = []; for ( var i = 0, len = array.length; i < len; i++){ res.push(func(array[i])); } return res; } var mapped = map([1, 3, 5, 7, 8], function (n){ return n = n + 1; }); print(mapped); var mapped2 = map(["one", "two", "three", "four"], function (item){ return "("+item+")"; }); print(mapped2);

The following result is printed:
2, 4, 6, 8, 9
(One), (two), (three), (four) // brackets each string in the array

Both mapped and mapped2 call map, but the results are quite different, because map parameters have already been abstracted once, and map functions are abstracted for the second time, A higher level can be understood as an abstract level.
Functional Programming in JavaScript
JavaScript is a widely misunderstood language. Because it was full of a lot of copy-paste code in early Web development, the quality of JavaScript code is usually not high, in addition, JavaScript code is constantly flashing gif advertisements, limiting the replication of webpage content and so on. Therefore, many people, including Web developers, are reluctant to learn JavaScript.
This situation was completely reversed in the Ajax renaissance. The emergence of Google Map, Gmail, and other Ajax applications surprised people that JavaScript could still do this! Soon, a large number of excellent JavaScript/Ajax frameworks were emerging, such as Dojo, Prototype, jQuery, and ExtJS. These codes bring brilliant results to the page, while allowing developers to see the elegance of functional language code.
Functional programming style
In JavaScript, a function itself is a special object that belongs to a top-level object and does not depend on any other object. Therefore, a function can be used as an outgoing/incoming parameter and stored in a variable, and everything that other objects can do (because a function is an object ).
JavaScript is called LISP with C syntax. A notable feature of LISP code is a large number of parentheses and the front function names, such:

Listing 4. Addition in LISP
(+ 1 3 4 5 6 7)

The plus sign is a function in LISP. This expression means to add all the numbers behind the plus sign and return the value. JavaScript can define the same sum function:

Listing 5. sum in JavaScript

function sum(){ var res = 0; for ( var i = 0, len = arguments.length; i < len; i++){ res += parseInt(arguments[i]); } return res; } print(sum(1,2,3)); print(sum(1,2,3,4,6,7,8));

Run the code to obtain the following results:
6
31

To fully simulate the functional encoding style, we can define the following:
Listing 6. Some simple function abstractions

Function add (a, B) {return a + B;} function sub (a, B) {return a-B;} function mul (a, B) {return a * B;} function p (a, B) {return a/B;} function rem (a, B) {return a % B;} function inc (x) {return x + 1;} function dec (x) {return x-1;} function equal (a, B) {return a = B;} function great (, b) {return a> B;} function less (a, B) {return
 
  

Such small functions and predicates make it easier for people with functional programming experience to write code:
Listing 7. Functional programming style

// Modify the previous Code function factorial (n) {if (n = 1) {return 1;} else {return factorial (n-1) * n ;}} // code function factorial (n) {if (equal (n, 1) {return 1;} else {return mul (n, n, factorial (dec (n )));}}

Closure and Its Use
Closure is an interesting topic. When another function inner is defined in the outter of a function, and inner references the variables in the outter scope, the inner function is used outside the outter, the closure is formed. Although the description is complex, the closure feature is often unintentionally used in actual programming.
Listing 8. Example of a closure

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 () {return n ++;} contains a reference to outter's local variable n. Therefore, when outter returns, the value of n is retained (not recycled by the garbage collection mechanism), and the value of n is changed when o1 () is continuously called. However, the o2 value does not change with o1 (). When o2 is called for the first time, n = 0 is returned. In object-oriented terms, that is, o1 and o2 are different instances and do not interfere with each other.
In general, the closure is very simple, isn't it? However, closures can bring many benefits, such as the ones we often use in Web development:
Listing 9. Closure in jQuery

var con = $("p#con"); setTimeout( function (){ con.css({background:"gray"}); }, 2000);

The above Code uses the jQuery selector to find the p element with the id of con and register the timer. After two seconds, set the background color of the p to Gray. The magic of this code snippet is that after the setTimeout function is called, con is still kept inside the function. After two seconds, the background color of the p element whose id is con is indeed changed. It should be noted that setTimeout has been returned after the call, but con is not released because con references the global scope variable con.
Using closures makes our code more concise, and more detailed descriptions of closures can be found in reference information. Due to the special nature of the closure, you must be careful when using the closure. Let's look at a confusing example:
Listing 10. Incorrect Closure

var outter = []; function clouseTest () { var array = ["one", "two", "three", "four"]; for ( var i = 0; i < array.length;i++){ var x = {}; x.no = i; x.text = array[i]; x.invoke = function (){ print(i); } outter.push(x); } }

The above code snippet is very simple. It saves multiple such JavaScript objects to the outter array:

Listing 11. Anonymous objects

{No: Number, text: String, invoke: function () {// print your no field }}

Let's run this Code:
Listing 12. incorrect results

ClouseTest (); // call this function to add the object for (var I = 0, len = outter. length; I <len; I ++) {outter [I]. invoke ();}

Unexpectedly, this code will print:
4
4
4
4
Instead of 1, 2, 3, 4. Let's take a look at what happened. Every internal variable x has its own no, text, and invoke fields, but invoke always prints the last I. Originally, the function we registered for invoke is:

Listing 13. error causes

function invoke(){ print(i); }

This is true for every invoke. When you call outter [I]. when invoke is used, the value of I will be obtained. Because I is a local variable in the closure, the value of for loop is 4 at the end of the exit, so every element in the outter call will get 4. Therefore, we need to transform this function:

Listing 14. Correct Use of closures

var outter = []; function clouseTest2(){ var array = ["one", "two", "three", "four"]; for ( var i = 0; i < array.length;i++){ var x = {}; x.no = i; x.text = array[i]; x.invoke = function (no){ return function (){ print(no); } }(i); outter.push(x); } }

By turning the function colialized, we registered this function for each element of outter this time:

//x == 0 x.invoke = function (){print(0);} //x == 1 x.invoke = function (){print(1);} //x == 2 x.invoke = function (){print(2);} //x == 3 x.invoke = function (){print(3);}

In this way, you can get the correct result.
Examples in practical application
Now we have enough theoretical knowledge. Let's take a look at JavaScript functional programming in the real world. Many people have made a lot of effort to make JavaScript object-oriented (JavaScript itself is programmable). In fact, object-oriented is not necessary, functional programming or mixed use of the two can make the code more elegant and concise.
JQuery is a very good JavaScript/Ajax framework with a small, flexible, and plug-in mechanism. In fact, jQuery has many plug-ins, such as expression verification, client image processing, UI, and animation. JQuery's biggest feature, as it claims, has changed the style of JavaScript code.
Elegant jQuery
Experienced front-end development engineers will find that the most common work done at ordinary times has a certain pattern: select some DOM elements and then apply some rules to these elements, such as modifying style sheets, register the event processor. Therefore, jQuery implements the perfect CSS selector and provides cross-browser support:
Listing 15. jQuery Selector

Var cons = $ ("p. note "); // find all p var con with the note class =$ (" p # con "); // find the p element var links = $ ("a") with the id of con; // find all the link elements on the page

Of course, jQuery's selector rules are rich. Here we will talk about the fact that the jQuery object selected with the jQuery selector is essentially a List. As in the LISP language, all functions are List-based.
With this List, we can do the following:
Listing 16. jQuery operations on jQuery objects (List)

cons.each( function (index){ $( this ).click( function (){ //do something with the node }); });

I want to use map with all the elements in the cons List (remember the map we mentioned earlier? ), The operation result is still a List. We can expand or narrow this list at will, for example:
Listing 17. Expanding/downgrading the jQuery set

Cons. find ("span. title "); // in p. note for more detailed filtering cons. add ("p. warn "); // Set p. note and p. warn is merged into cons. slice (0, 5); // obtain a subset of cons

Let's look at a small example. Suppose there is a page like this:
Listing 18. HTML structure of the page

Hello, world

345

Hello, world

67

483

The effect is as follows:
Figure 1. Effect Before Filtering
We use jQuery to filter the packaging set once. jQuery's filter function can make the selected list object retain only the objects that meet the conditions. In this example, we keep such p, if and only when this p contains a span class named title, and the content of this span is a number:
Listing 19. Filtering Sets

Var cons = $ ("p. note "). hide (); // select the p of the note class and hide cons. filter (function () {return $ (this ). find ("span. title "pai.html (). match (/^ \ d + $ /);}). show ();

Shows the effect:
Figure 2. effect after filtering
Let's take a look at the Array Operations in jQuery (in essence, arrays in JavaScript are similar to lists), such as the map function and filter mentioned in the previous example:
Listing 20. jQuery's functional operations on Arrays

var mapped = $.map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function (n){ return n + 1; }); var greped = $.grep([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function (n){ return n % 2 == 0; });

Mapped will be assigned the following values:
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Greped is:
[2, 4, 6, 8, 10]
Let's look at a more practical example:
Listing 21. An example of page refresh

function update(item){ return function (text){ $("p#"+item).html(text); } } function refresh(url, callback){ var params = { type : "echo", data : "" }; $.ajax({ type:"post", url:url, cache: false , async: true , dataType:"json", data:params, success: function (data, status){ callback(data); }, error: function (err){ alert("error : "+err); } }); } refresh("action.do/op=1", update("content1")); refresh("action.do/op=2", update("content2")); refresh("action.do/op=3", update("content3"));

First, declare a colized function update. This function uses the input parameter as the selector id and updates the content of this p (innerHTML ). Then declare a function refresh. refresh accepts two parameters. The first parameter is the server url, and the second parameter is a callback function. When the server returns the result successfully, this function is called.
Then we call refresh three times in succession. The url and id of each refresh are different, so that the content of content1, content2, and conetent3 can be updated asynchronously. This mode is quite effective in actual programming, because about how to communicate with the server, and if the part of the page content is abstracted into a function, now we need to pass the url and id to refresh to complete the required action. Function programming greatly reduces the complexity of this process, which is the final reason we choose to use this idea.
Conclusion
In actual applications, it is not limited to functional or object-oriented methods. Usually, they are used in combination. In fact, many mainstream object-oriented languages are constantly improving themselves, for example, some features of functional programming languages are added. In JavaScript, the two are well combined. The code can be very simple, elegant, and easier to debug.
This article only mentions a small part of jQuery features. If you are interested, you can find more links in references. jQuery is very popular, therefore, you can find many articles about how to use it.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.