Basics of functional programming in JavaScript

Source: Internet
Author: User
This article mainly introduces the basic guide to JavaScript functional programming. Although JavaScript has been repeatedly emphasized as object-oriented by many people, there are no classes in JavaScript, the js programming dominated by functions presented in this article can also be very nice. For more information, see Introduction

JavaScript is a powerful but misunderstood programming language. Some people like to say that it is an object-oriented programming language or a functional programming language. Others prefer to say that it is not an object-oriented programming language, or it is not a functional programming language. Some people think that it has both the characteristics of object-oriented and functional languages, or that it is neither object-oriented nor functional. Well, let's put aside those arguments first.

Let us assume that we have a common mission: to write programs within the scope permitted by the JavaScript language, use as many functional programming principles as possible.

First, we need to clear up the misconceptions about functional programming in our minds.

Function programming misunderstood in the JS Field

It is clear that a considerable number of developers use JavaScript in the functional paradigm one day to night. I still want to say that there are more JavaScript developers and they do not really understand the true meaning of the hypothetical act.

I'm sure this is because many web development languages for the server end are from the C language, while C is obviously not a functional programming language.

There seems to be two levels of confusion. The first level of confusion is explained by the following examples that are often used in jQuery:

$(".signup").click(function(event){  $("#signupModal").show();  event.preventDefault();});

Hey, take a closer look. I pass an anonymous function as a parameter, which is known as the "CallBack" function in the JavaScript world.

Does anyone think This is functional programming? Not at all!

This example shows the key features of a functional language: functions as parameters. On the other hand, this three-line code example also violates almost all other functional programming paradigms.

The confusion at the second level is a bit subtle. Here, some JS developers pursuing the trend are secretly thinking about it.

Okay, nonsense! But I already know all the knowledge and skills about functional programming. I use Underscore. js on all my projects.

Underscore. js is a popular JavaScript library that is used everywhere. For example, I have a group of words. I need to get a set. Each element in the set is the first two letters of each word. Using Underscore. js is quite simple:

var firstTwoLetters = function(words){  return _.map(words,function(word){    return _.first(word,2);  });};

Look! Look at JavaScript wizards. I am using these advanced functional applications, such as _. map and _. first. What else do you have to say, Leland )?

Although underscore and functions like _. map are very valuable functional paradigms, the methods used to organize code in this example seem to be... Long and hard for me to understand. Do we really need to do this?

If we start to think a little more about functional thinking, we may be able to change the above example to this:

//... A little magic var firstTwoLetters = map (first (2 ));

Think about it. One line of code contains the same information as the preceding five lines of code. Words and word are only parameters/placeholders. The core of this method is to combine the map function, first function, and constant 2 in a more obvious way.

Is JavaScript a functional programming language?

There is no magic formula to determine whether a language is a functional language. Some languages are obviously functional, just as some other languages are obviously not functional, but many languages are ambiguous median.

So here are some common and important functional language "ingredients" (JavaScript can be implemented with bold marks)

  • The function is a "first-class citizen"
  • Functions can return functions.
  • Closure supported in lexical form
  • The function must be "pure"
  • Reliable Recursion
  • No mutations

This is by no means a list of them, but we should at least discuss the three most important features in Javascript one by one. They support programming in a functional way.

Let's take a closer look:

The function is a "first-class citizen"

This one may be the most obvious among all ingredients and may be the most common in many modern programming languages.

In JavaScript, local variables are defined by the var keyword.

var foo = "bar";

Defining a function as a local variable in JavaScript is very easy.

var add = function (a, b) { return a + b; };var even = function (a) { return a % 2 === 0; };

These are all facts. variables: The add and even variables are assigned a value to establish a reference relationship with the function definition. Such a reference relationship can be changed at any time.

// capture the old version of the functionvar old_even = even;  // assign variable `even` to a new, different functioneven = function (a) { return a & 1 === 0; };

Of course, this is nothing special. But being a "first-class citizen" makes it possible to pass functions to another function as parameters. For example:

var binaryCall = function (f, a, b) { return f(a, b); };

This is a function. It accepts a binary function f and two parameters a and B, and then calls this binary function f. The binary function f Takes a and B as the input parameters.

add(1,2) === binaryCall(add, 1, 2); // true

This looks a little clumsy, but when you consider the next functional programming "ingredients", it's obvious...

Function can return functions (in other words, "Higher-order functions ")

Things are getting cool. Although it is relatively simple to start. The function finally uses the new function as the return value. For example:

var applyFirst = function (f, a) {  return function (b) { return f(a, b); };};

This function (applyFirst) accepts a binary function as one of the parameters. You can regard the first parameter (that is, the binary function) as the "partial operation" of this applyFirst function ", then, a mona1 (a parameter) function is returned. When the mona1 function is called, the binary function f (a, B) of the first parameter (f) of the external function is returned ). Returns the binary functions of two parameters.

Let's talk about some functions, such as the mult (multiplication) function:

var mult = function(a, b) { return a * b; };

According to the mult (multiplication) function logic, we can write a new function double (multiplication ):

var double = applyFirst(mult, 2); double(32); // 64double(7.5); // 15

This is a partial function, which is often used in FP. The full name of FP is Functional Programming)

Of course, we can define functions like applyFirst:

var curry2 = function (f) { return function (a) {  return function (b) {   return f(a, b);  }; };};

Now, I want a double (multiplication) function. Let's do it in another way:

var double = curry2(mult)(2);

This method is called "function kerialization ". It is somewhat similar to partial application (partial function application), but it is bigger.

To be accurate, functional programming is most powerful. Simple and easy-to-understand functions are the basic components for building software. When there is a high level of organizational capability and little reuse logic, functions can be combined and mixed to express more complex behavior.

Higher-order functions have more fun. Let's look at two examples:

1. Flip binary function parameter order

// flip the argument order of a functionvar flip = function (f) { return function (a, b) { return f(b, a); };}; pide(10, 5) === flip(pide)(5, 10); // true

2. Create a function that combines other functions

// return a function that's the composition of two functions...// compose (f, g)(x) -> f(g(x))var compose = function (f1, f2) { return function (x) {  return f1(f2(x)); };}; // abs(x) = Sqrt(x^2)var abs = compose(sqrt, square); abs(-2); // 2

This example creates a practical function that we can use to record each function call.

var logWrapper = function (f) { return function (a) {  console.log('calling "' + f.name + '" with argument "' + a);  return f(a); };};var app_init = function(config) { /* ... */ }; if(DEBUG) { // log the init function if in debug mode app_init = logWrapper(app_init);} // logs to the console if in debug modeapp_init({ /* ... */});

Lexical closure + Scope

I am confident that understanding how to effectively use closures and scopes is the key to becoming a great JavaScript developer.
So... What is a closure?

To put it simply, a closure is an internal function that has always been authorized to access the scope of the parent function, even if the parent function has been returned. <译注4>
An example may be required.

var createCounter = function () { var count = 0; return function () {  return ++count; };}; var counter1 = createCounter(); counter1(); // 1counter1(); // 2 var counter2 = createCounter(); counter2(); // 1counter1(); // 3

Once the createCounter function is called, the variable count is allocated with a new memory area. Then, a function is returned, which holds a reference to the variable count and executes the count plus 1 operation each time it is called.

Note that from outside the scope of the createCounter function, we cannot directly operate the count value. Counter1 and Counter2 functions can operate copies of their respective count variables, but only

It is often supported to operate count (auto-increment 1) in a specific way.

In JavaScript, the boundary check of the scope is only performed when the function is declared. One function by one, and only one function by one, with their respective scope tables. (Note: This is no longer the case in ECMAScript 6 because of the introduction of let)

Some further examples are provided to prove this point:

// global scopevar scope = "global"; var foo = function(){ // inner scope 1 var scope = "inner"; var myscope = function(){  // inner scope 2  return scope; }; return myscope;}; console.log(foo()()); // "inner" console.log(scope); // "global"

There are still some important things to consider about the scope. For example, we need to create a function that accepts a number (0-9) and returns the corresponding English name of the number.

To put it simply, someone will write:

// global scope...var names = ['zero','one','two','three','four','five','six','seven','eight','nine'];var digit_name1 = function(n){ return names[n];};

However, the disadvantage is that the names definition is in the global scope and may be accidentally modified. This may result in incorrect results returned by the digit_name1 function.
Write as follows:

var digit_name2 = function(n){ var names = ['zero','one','two','three','four','five','six','seven','eight','nine']; return names[n];};

This time, the names array is defined as the digit_name2 local variable. this function is far away from unexpected risks, but results in performance loss. Every time digit_name2 is called, it will define and allocate space for the names array. In another example, if names is a very large array, or the digit_name2 function may be called multiple times in a loop, the performance impact will be very obvious.

// "An inner function enjoys that context even after the parent functions have returned."var digit_name3 = (function(){ var names = ['zero','one','two','three','four','five','six','seven','eight','nine']; return function(n){  return names[n]; };})();

At this time, we are faced with the third choice. Here we implement the Function Expression called Immediately, instantiate the names variable only once, then return the digit_name3 Function, and execute the Expression Immediately in the IIFE (Immediately-Invoked-Function-Expression) the closure function holds a reference to the names variable.
This solution has the advantages of the first two and avoids disadvantages. Done! This is a common mode used to create a "private" state that cannot be modified by the external environment.

Related Article

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.