JavaScript Heigher-order function

JavaScript Heigher-order function

Personal blog/blog garden

The function defined in "javascript design pattern and development practice" can be passed as a parameter or output as a return value

The following conditions:

  1. Accept one or more functions as input
  2. Output a function

Higher-order functions are generally those functional types that contain more than functions. In functional programming, a higher-order function that returns another function is called a curry function.

Function passed as a parameter

By passing the function as a parameter, we can extract part of the business logic that is easy to change, so that the changed and unchanged parts of the business code can be separated

Callback:

Pass a function into a method, the function will not be executed immediately, it will be executed after waiting for the result.

let func = function (callback){
    if(n === 'owen'){
        callback() //
    }
}
 function say (){
     console.log('Hello Word')
 }
 func(say)
 

Commonly used methods of Array objects

[1,2,3,4].forEach(iteration)
 function iteration(v){
     console.log(v)
 }
 

Output as return value

Let the function continue to return to an executable function, which means that the running process is continuous.

Determine the data type

let type = type =>{
    return obj => Object.prototype.toString.call(obj) === `[object ${type}]`
}
let isArray = type('Array'),isString = type('String'),isNumber = type('Number'),isObject = type('Object');

//or
let Type = (function(){
    let type = {},types = ['Object','Array','Number','String']
    for (let val of  types) {
        (function(str){
            type[`is${str}`] = (obj) => Object.prototype.toString.call( obj ) === `[object ${str}]`
        }(val))
    }
    console.log(type)
    return type
}())
Type.isNumber(2) //true
 

Implement AOP (slice-oriented programming)

AOP is a technology that realizes the unified maintenance of program functions through pre-compilation and runtime dynamic agents. AOP in JAVA language separates some functions that are not related to core business logic modules, usually including log statistics, security control, and exception handling lights. Then it is incorporated into the business logic by means of "dynamic weaving".

Benefits: It can maintain the purity and high cohesion of business logic modules, and facilitate the reuse of functional modules such as log statistics.

Implementing AOP in JavaScript means to "dynamically weave" a function into another function

Implementation:

Function.prototype.before = function(beforeFn){
    let that = this; //    func   func

    return function( ...args){
        beforeFn.apply(this,args) //  beforeFn
        return that.apply(this,args) // 
    }
}

Function.prototype.after = function(afterFn){
    let that = this; //   befor  befor
    return function( ...args){
        let ret = that.apply(this,args) // 
        afterFn.apply(this,args) //   beforeFn
        return ret
    }
}
var func = function (){
    console.log(2)
}
func = func.before(function (){
    console.log(1)
}).after(function (){
    console.log(3)
})
func()
//1 2 3
 

Function currying

In mathematics and computer science, currying is to convert a function with multiple parameters into a series of functions that use one parameter, and return a new function that accepts the remaining parameters

curring is also called partial evaluation; a curring function first receives some parameters, the function does not evaluate immediately, but continues to return to another function, and the parameters just passed in will be saved in the formed closure. When a function really needs a value, all previous parameters will be used for evaluation at one time

Simple example:

function add(a,b) {
    return a + b
}
add(1,2) //3

 

Next, use currying to implement a function of the sum of consumption within a few days

// 
var cost = (function() {
    var args = [];
    return function(){
        if(!arguments.length){
            let money = 0
            for (let val of args ){
                money += val;
            }
            return money
        }else{
            [].push.apply(args,arguments)
        }
    }
})()

cost(100);
cost(100);
cost(100);
cost(); //300

//currying
/**
 *  
 */

// func(100,100,100)//300
function count (...args){
    let num = 0;
     if(args.length>1){
         for (let v of args){
             num +=v
         }
         return num
     }else{
         return args[0]
     }
}

var  curry = function(func){
        let args = []
    return function fn(...Args){
        if (Args.length){
            [].push.apply(args,Args)
            return fn
        }else{
            return func.apply(this,args)
        }
    }
}
cost = curry(count);

cost(100);
cost(100);
cost(100);
cost(); //300

 

Function throttling

In most cases of JavaScript, the user initiates the function actively. Unless the implementation of the function itself is unreasonable, it will generally not encounter performance-related problems. In a few cases, the function is not directly triggered by the user and may be called frequently. Performance issues. such as:

window.addEventListener('resize', function(e) {
   //do something...
});
window.addEventListener('scroll', function(e) {
   //do something...
});
Dom.addEventListener('mousemove', function(e) {
   //do something...
});

//progress
xhr.upload.addEventListener("progress", function(result) {
    //do something...
}, false);

//...
 

The above events are triggered many times per second, and often manipulate DOM nodes, which is very performance-consuming, and the browser will be overwhelmed and stuck; in fact, we do not need to trigger such a high frequency, so we can ignore some execution times in a period of time.

Throttling principle

If the event continues to be triggered, it can be executed only once at intervals.

Use timers to achieve throttling

Function to be executed with setTimeouta time delay function is executed, if the timer is not complete execution of the function to be executed took down are ignored.

 function throttle(func,wait) {
      let timer, firstFlag = true; //
      return function(...args) {
          if(timer)  return false; // 

          let that = this;
          if(firstFlag){
              firstFlag = false;
             return func.apply(that,args);
          }
          timer = setTimeout(function(){
               clearTimeout(timer);
               timer = null;
               func.apply(that,args);
            },wait)
      }
 }
 window.addEventListener('scroll', throttle(function(e) {
  console.log(e) 
},1000));
 

Function stabilization

Unlike throttling that only calls the event processing function once within a certain period of time, anti-shake is that the event processing function will only be executed once if the event is not triggered within a certain period of time. If the event is triggered again before the set time comes, it will Restart the delay. (The user does not trigger the corresponding event and executes the event only once)

function debounce(func,wait) {
    let timer;
    return function(...args) {
        let that = this;
        clearTimeout(timer);
        timer = setTimeout(function(){
            func.apply(that,args)
        },wait)
    }
}
 window.addEventListener('scroll', debounce(function(e) {
  console.log(e) 
},1000));
 

Reference

"JavaScript Design Patterns and Development Practice"

Kivi AOP

Base dimension higher order function

JavaScript topics follow the underscore learning throttling