In-depth understanding of javascript functions series sixth - higher-order functions

1. Definition

Higher-order function: functions in javascript actually point to a variable. Since a variable can point to a function (representing a function with a variable), and the parameters of a function can receive variables, then one function can accept another A function as a parameter is called a higher-order function, that is, a function that operates on a function. There are two cases:

  • Functions can be passed as parameters
  • Functions can be output as return values

Functions in javascript show that the conditions for higher-order functions are satisfied. In actual development, whether the function is passed as a parameter, or the execution of the function returns another function. There are many application scenarios for both scenarios. They are described in detail below.

2. Functions are passed as parameters

Passing the function as a parameter means that a part of the business logic that is easy to change can be extracted and placed in the function parameter, so that the changed part and the unchanged part of the business code can be separated. One of the most common application scenarios is the callback function.

【Callback】

In the application of ajax asynchronous request, the use of callback function is very frequent. When you want to do something after the ajax request returns, but you don't know the exact time when the request returns, the most common solution is to pass the callback function as a parameter to the method that initiates the ajax request, and execute the callback function after the request is completed.

var getUserInfo = function( userId, callback ){
  $.ajax( 'http://xx.com/getUserInfo?' + userId, function( data ){
    if ( typeof callback === 'function' ){
      callback( data );
    }
  });
}
getUserInfo( 123, function( data ){ 
  alert ( data.userName );
});

The application of callback functions is not only in asynchronous requests. When a function is not suitable for executing some requests, these requests can also be encapsulated into a function and passed as a parameter to another function to delegate another function to execute.
For example: want to create 100 div nodes on the page, and then set these div nodes to be hidden, the following is a way to write code.

var appendDiv = function(){
  for ( var i = 0; i < 100; i++ ){
    var div = document.createElement( 'div' );
    div.innerHTML = i;
    document.body.appendChild( div );
    div.style.display = 'none';
  }
};
appendDiv();

It is unreasonable to hard-code the div.style.display = "none"logic of to display in appendDiv. The functions of appendDiv are too diverse and become a function that is difficult to reuse. Not everyone chooses to hide it immediately after creating a node.

So div.style.display = "none"extract this line of code, encapsulate it into a function, and pass it into the appendDiv() method in the form of a callback function.

 var appendDiv = function(callback) {
        for(var i=0; i<100; i++) {
            var div = document.createElement("div");
            div.innerHTML = i;
            document.body.appendChild(div);
            if(typeof callback == "function") {
                callback(div);
            }
        }
    };

 appendDiv(function(node) {
        node.style.display  = "none";
 });

It can be seen that the request for the hidden node is actually initiated by the client, but the client does not know when the node will be created, so the logic of the hidden node is placed in the callback function. "Delegates" to the appendDiv() method. The appendDiv() method of course knows what the node is created, so when the node is created, appendDiv() will execute the callback function passed in by the user before.

[Array sorting]
Another common scenario where a function is passed as a parameter is the sort() function of the array sorting function. Array.prototype.sort accepts a function as a parameter, this function defines the rules for sorting the elements of the array (positive order or reverse order). The purpose is to sort the array, which is the invariant part; and what rules are used to sort it is the variable part. Encapsulate the variable part into the function, and dynamically pass in Array.prototype.sort, so that Array.prototype.sort can be flexibly controlled by us.

// 从小到大排列,输出: [ 1, 3, 4 ]
[ 1, 4, 3 ].sort( function( a, b ){ 
  return a - b;
});

// 从大到小排列,输出: [ 4, 3, 1 ]
[ 1, 4, 3 ].sort( function( a, b ){ 
  return b - a;
});

3. The function is output as a return value

Compared with passing the function as a parameter, there are many application scenarios for the function as the return value output. Let the function continue to return an executable function, which means that the operation process is sustainable.
The following is a series of isType functions that use the Object, prototype.toString method to determine the data type.

var isString = function( obj ){
  return Object.prototype.toString.call( obj ) === '[object String]';
};
var isArray = function( obj ){
  return Object.prototype.toString.call( obj ) === '[object Array]';
};
var isNumber = function( obj ){
  return Object.prototype.toString.call( obj ) === '[object Number]';
};

In fact, most of the implementations of these functions are the same, the only difference is the string returned by Object.prototype.toString.call(obj). In order to avoid redundant code, these strings can be passed as parameters to the isType function in advance. code show as below:

var isType = function( type ){ 
  return function( obj ){
    return Object.prototype.toString.call( obj ) === '[object '+ type +']';
  }
};

var isString = isType( 'String' ); //调用这个函数返回的是内层函数
var isArray = isType( 'Array' ); 
var isNumber = isType( 'Number' );

console.log( isArray( [ 1, 2, 3 ] ) );    // 输出:true

Of course, you can also use a loop statement to register these functions in batches.

 var Type = {};
   for(var i=0, type; type = ['String', 'Array', 'Number' ][i++];) {
       (function(type) {
           Type['is' + type] = function(obj) {
               return Object.prototype.toString.call(obj) == "[object " + type +"]";
           }
       })(type)
   }

console.log(Type.isArray([])); //true
console.log(Type.isString("str")); //true

Reprinted from: Little Match's Blue Ideal
http://www.cnblogs.com/xiaohuochai/p/5613593.html
When reading the teacher's blog, I treat it as a book, so most of my blogs come from the teacher's blog The original words and examples, plus some of my own understanding, and made appropriate annotations, and some tests on the teacher's code.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325764535&siteId=291194637