1. What is caching?

The so-called function cache is to cache the result of the function operation, which is a typical way to exchange memory for performance. It is often used to cache data calculation results and cache objects. A cache is simply a temporary data store that holds data so that future requests for that data can be processed more quickly


2. Why do we need to do function caching?

In the front-end page, some data (such as data dictionary data) can be saved in the JS object at the time of the first request, so that you do not need to request the server every time. For pages that make heavy use of data dictionaries to populate drop-down boxes, this approach can greatly reduce access to the server. Simply put, it is to provide convenience, reduce the number of queries and the consumption of time.


3. What is the implementation principle of function caching?

The concept of caching in JavaScript is based on two concepts:

  • closure
  • Higher-order functions

closure

A closure is a combination of a function and the lexical environment in which it is declared.


What closures do: Closures are one of javascript’s most difficult and distinctive features. Many advanced applications rely on closures. Closures can be used in many ways. It is useful for reading variables inside a function and for keeping the values of these variables in memory and not being automatically cleared after a function is called. I think a good understanding of closures is that you want to reuse variables without contaminating them globally. Here’s a small example:

var object = {
    fn: function() {let result = new Array()
        for(var i =0; i < 10; i++) {
            result[i] = function (num) {
                return num;
            }(i)
        }
        return result
    }
}
          
console.log(object.fn());
//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Copy the code

How it works: Since for executes an anonymous function every time, each execution has its own execution environment and scope. In JavaScript, all functions have access to the scope at the level above them. So you define a child function inside the parent function, and the child function has access to the parent function’s variables. Subfunctions are equivalent to closures. If we define the counter I inside the parent function, then we call the counter I inside the child function and execute the child function outside the parent function to count. This counter can only be accessed by nested functions and will not be reset each time (since we are executing a child function, this counter will only be reset if the parent function is executed).

ES5 has only functional scope and global scope, which leads to a lot of irrational scenarios. For example, an inner variable may override an outer variable; Loop variables used to count are leaked as global variables. Closures may be needed at this point. ES6, however, has a new let const keyword with unique block-level scope, so the advent of block-level scope virtually eliminates the need for the widely used immediate-execution function expressions.

Higher-order functions

JavaScript functions actually refer to a variable. Since variables can point to functions and arguments to functions can accept variables, a function can accept arguments to another function, which is called a higher-order function. In plain English, a function that returns a function

Let’s look at a small example of higher-order functions combined with closures:

var add = function() {
    var num = 0
    return function(a) {
        return num = num + a
    }
}
add()(1)      // 1
add()(2)      // 2Copy the code

Note: The two add()(1) and add()(2) do not affect each other, which means that each time you run add, you return a different anonymous function. In fact, each time you run add, the return function is different, so the result of running will not be affected. The main use of closures is to preserve scope.

If written differently, for example:

var add = function() {
    var num = 0
    return function(a) {
        returnnum = num + a } } var adder = add() adder(1); // 1 adder(2); / / 3Copy the code

In this case, the operation will continue based on the result of the previous operation, meaning that both adder runs with the same num.

4.JS function cache

Here the ideas of the higher-order functions can be used to realize a simple cache, inside the function with an object storage input parameters, if next time input the same parameters, then compare the attributes of the object, the value from the object out, don’t have to continue to run, thus greatly save the waiting time for the client.

  const memorize = function(fn) {const cache = {} // The object that stores cached datareturn function(... Args) {const _args = json.stringify (args) // use the parameter as the cache keyreturnCache / _args | | (cache [_args] = fn. Apply (fn, args)) / / if have cache, the value directly. Otherwise recalculate and cache}} const add =function(a, b) {
    console.log('Start cache')
    return a + b
  }

  const adder = memorize(add)

Copy the code

Sum = sum; sum = sum; sum = sum; sum = sum

Console. log(adder(2, 6)) // Start cache 8 // cache: {'[2, 6]': 8} console.log(adder(2, 6))'[2, 6]': 8} console.log(adder(10, 10))'[2, 6]': 8, '[10, 10]'20} :Copy the code

“Start cache” is printed only for the first time. After that, as long as the parameter is the same, the value will be fetched from the cache each time. The cache cannot be a Map data structure because Map keys are compared using ===, [1]! ==[1], so even if the same object or array is passed in, it will still be stored as different keys.

5. At the end

Functional programming is becoming more and more popular and important! As a novice, we also need to learn more, see more, practice more. After reading this article, I hope you can realize it yourself, just as the so-called eye over a thousand times is better than hand over! If this article can help you, I hope you can manually click the “like” ~ god ~ I heard that the “like” friends are off the single??