Process abstraction of writing JS principles

Posted by dror_israel on Sun, 23 Jan 2022 08:16:46 +0100

Process abstraction

Process abstraction

  • Used to handle local detail control
  • Process abstraction is the basis of function thought

    In the process of imagination abstraction, it can be abstracted into a room, the door and window in the room, and then the room space itself is data, but the action and behavior of opening the door or window is a process, that is to say, we can not only abstract the door, window and space into data, but also open the process as an abstract object.

Limit of operation times

Restrictions on the number of operations common scenarios are

  • Some asynchronous interactions
  • One time HTTP request

By using a higher-order function and taking the function as a parameter, you can write a function that is executed only once or a limited number of times, such as the following Once() function. The parameter of this function is a function fn, and then a function will be returned during execution. Judge whether FN exists in the middle of the returned function. If it exists, execute FN with the actual parameters, Then fn=null so that the function will not be executed next time. For example, I declare a show function, which asks for the sum of a+b, and prints the string. Below I say this function assigns to foo=once(show), then calls three times foo(), the console only executes once.

function once(fn){ 
    return function(...args){
        if(fn){ //Judge whether the function exists. If so, call it with the actual parameters, and then set it to null
            const ret = fn.apply(this, args);// Execute function with actual parameters
            fn = null;// If it is blank, the judgment statement will not be executed next time, and the function will not be called
            return ret;// Return the result of fn
        }
    }
}
function show(a, b) {
    let ans = a + b
    console.log("Hit it~");
    return ans
}
let foo = once(show);
console.log(foo(10, 20));//"Hit ~ 30"

console.log(foo(30, 40));//undeifined
console.log(foo(50, 60));//undeifined

Once

  • In order to enable the "execute once" requirement to cover different event processing, we split the requirement. This process is called process separation

Higher order function

Higher order function

  • Take function as parameter
  • Take function as return value
  • Often used as a function decorator


HFH0 function

function HOH0(fn) {
    return function (...args) {
            return fn.apply(this, args);
        }
    }
}

HFH0 function is also called level 0 higher-order function and equivalent decorator. No matter what kind of fn you pass, it will execute fn with original parameters. Calling HFH0(fn) to execute fn is equivalent to direct execution fn. It is also called equivalent normal form in high-order functions. once() and other functions are extended based on this equivalent normal form

Other commonly used higher-order functions

Once

Up there~

Throttle function

Click here to view the example

Function of throttling function: suppose that the background needs to record a user's behavior, such as mouse movement, but the user will often move the mouse. Even if the user moves a little, he will send a lot of data to the background, which will cause a great waste of bandwidth. The data of the mouse moved by the user does not mean to be completely sent to the background, We can set an interval to record data once to limit its data.

Idea of anti shake function: using the idea of advanced function, take the original function fn as the parameter and return a function as the result. We will set a timer. If the timer does not exist, execute FN. At the same time, we will register a setTimeout for the timer. After the specified time, the timer = null. No matter how long the timer exists, we will call the throttling function, because the timer is not empty, So they will not execute FN.

function throttle(fn, time = 500){
  let timer;
  return function(...args){
    if(timer == null){ // If the timer is not empty, it will not enter the judgment body and will not execute fn again
      fn.apply(this,  args);
      timer = setTimeout(() => {
        timer = null;
      }, time)
    }
  }
}

Anti shake function (Debounce)

Click here to view the example

Function of anti shake function: when recording the movement of the mouse, if we keep moving the mouse indiscriminately, the mouse will not be recorded. It will only be recorded when the mouse stops. For example, the bird below will not move when we move the mouse indiscriminately. It will only move when the mouse stops

Idea of throttling function: still use the idea of advanced function, still use a timer to record, clear the timer of the previous timer every time you move, and then re register a setTimeout timer for this timer. It will be executed only after the automatic execution of the timer is completed fn

function debounce(fn, dur){
  dur = dur || 100;
  var timer;
  return function(){
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, dur);//Only when the timer automatically ends will the function inside be called
  }
}

Consumer/2

Click here to view the example

function consumer(fn, time){
  let tasks = [],
      timer;
  
  return function(...args){
    tasks.push(fn.bind(this, ...args));
    if(timer == null){
      timer = setInterval(() => {
        tasks.shift().call(this)
        if(tasks.length <= 0){
          clearInterval(timer);
          timer = null;
        }
      }, time)
    }
  }
}

Batch operation element (Iterative)

Click here to view the example

This function is used to operate elements in batches, such as modifying the style of multiple elements, such as setting the color of multiple elements

First determine whether the object can be iterated, if it can iterate, take each element, then call the fn method, then push the result to the ret array and return it.

const isIterable = obj => obj != null 
  && typeof obj[Symbol.iterator] === 'function';//Declare a function to determine whether obj is an iteratable object
  
function iterative(fn) {
  return function(subject, ...rest) {
    if(isIterable(subject)) {
      const ret = [];
      for(let obj of subject) {
        ret.push(fn.apply(this, [obj, ...rest]));
      }
      return ret;
    }
    return fn.apply(this, [subject, ...rest]);
  }
}

Programming paradigm

  • Programming paradigm: many modern scripting languages, including JavaScript, are mixed programming paradigms. There are several categories of programming paradigms, including imperative and declarative.
  • Imperative is divided into procedural and object-oriented;
  • Declarative expressions are divided into logical expressions and functional expressions;
  • JavaScript, a modern scripting language, is a mixed programming paradigm. It has both imperative and declarative characteristics. Therefore, we can write code in imperative style or declarative style through JS. There is no difference between imperative and declarative. It supports two styles of languages at the same time, which makes the writing of JavaScript more flexible

Imperative style code

let list = [1, 2, 3, 4];
let map = [];
for (let i = 0; i < list.length; i++) {
    map.push(list[i] * 2);
}

Declarative style code

let list = [1, 2, 3, 4];
const double = x => x * 2;
list.map(double);

example

Imperative and declarative expressions will behave differently in different scenarios

Toggle – imperative

Click here to view the example

switcher.onclick = function(evt){
  if(evt.target.className === 'on'){
    evt.target.className = 'off';
  }else{
    evt.target.className = 'on';
  }
}

Toggle – declarative

Click here to view the example

function toggle(...actions){
  return function(...args){
    let action = actions.shift();
    actions.push(action);
    return action.apply(this, args);
  }
}

switcher.onclick = toggle(
  evt => evt.target.className = 'off',
  evt => evt.target.className = 'on'
);

Toggle – three states

Click here to view the example

If you want to add three or more states, you need to add an if---else branch if you want to add other states in the command form, and you need to add a state under the declaration form. In this example

function toggle(...actions){
  return function(...args){
    let action = actions.shift();
    actions.push(action);
    return action.apply(this, args);
  }
}

switcher.onclick = toggle(
  evt => evt.target.className = 'warn',
  evt => evt.target.className = 'off',
  evt => evt.target.className = 'on'
);

conclusion

Every point that teacher Yueying said is worth torturing. I have felt the difficulty since the beginning of the youth training camp. The road to the front is heavy and the road to the front is long~
attend to each one 's own duties: Blog links that perform their duties
Component encapsulation: Component encapsulated blog links
Process abstraction: where are you~

Topics: Javascript ECMAScript