Front-end learning now, found that some code usually read thousands of times, are about to see the vomit of the key moment of the code actually can not write out, this is really a little uncomfortable ah. So I’ll make some summaries here, and I’ll forget to review them in time. This series is roughly divided into four parts:

  1. Call, apply, bind, new, Currification, function combination, anti-shake, throttling
  2. The second part of array de-duplication, array flattening, thousandths, deep copy, promise implementation
  3. Article 3 Common sorting algorithms (in progress)
  4. Chapter 4 Algorithm questions often appeared in the interview of big factory (I am working on it)

1. Function.prototype.call

The call method calls a function with a specified this value and one or more arguments given separately. The call method accepts a list of arguments. The return value is the result of the function’s execution.

Function.prototype.myCall = function(context, ... args) {
    // Set the default value of the first argument to window
    const ctx = context || window;
    // Set a unique variable to prevent overwriting the original property
    const func = Symbol('func');
    ctx[func] = this;
    constresult = ctx[func](... args);// Delete the declared attribute before returning the value
    delete ctx[func];
    return result;
}
Copy the code

2. Function.prototype.apply

The apply method calls a function with a specified this value and a single argument. The apply method takes an array of arguments. The return value is the result of the function’s execution.

// The difference with call is shown in args. After call and apply are used, the arguments received by the original function should be the deconstructed arguments
Function.prototype.myApply = function(context, args) {
    // Set the default value of the first argument to window
    const ctx = context || window;
    // Set a unique variable to prevent overwriting the original property
    const func = Symbol('func');
    ctx[func] = this;
    constresult = ctx[func](... args);// Delete the declared attribute before returning the value
    delete ctx[func];
    return result;
}
Copy the code

3. Function.prototype.bind

The bind method accepts arguments, as does the original function, and both parts need to be preserved. Note that the bind function can be used as a constructor, so you need to be aware of the reference to this. Be careful to keep the properties and methods of the original function on the prototype chain. The return value is a new function.

// self-implement
Function.prototype.myBind = function(context, ... args) {
    const that = this;
    const funcBind = function() {
        // When the bind function is instantiated, apply points to the instance of the function
        const target = this instanceof funcBind ? this : context;
        const applyArgs = args.concat([...arguments]);
        that.apply(target, applyArgs);
    }
    // Apply does not retain the methods on the function prototype, a shallow copy is made here
    funcBind.prototype = Object.create(that.prototype);
    return funcBind;
}
/ / / MDN source implementation (https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)
// Does not work with `new funcA.bind(thisArg, args)`
if (!Function.prototype.bind) (function(){
  var slice = Array.prototype.slice;
  Function.prototype.bind = function() {
    var thatFunc = this, thatArg = arguments[0];
    var args = slice.call(arguments.1);
    if (typeofthatFunc ! = ='function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }
    return function(){
      var funcArgs = args.concat(slice.call(arguments))
      returnthatFunc.apply(thatArg, funcArgs); }; }; }) ();Copy the code

4. new

Creates an instance of a user-defined object type or of a built-in object with a constructor. MDN interpretation

  1. Create an empty object
  2. Make the new object inherit the stereotype of its constructor
  3. Executes the constructor and binds the new this pointer
  4. If the function itself returns an object, it returns the newly created object
function myNew(func, ... args) {
    The object.create () method creates a new Object, using an existing Object to provide the __proto__ of the newly created Object
    __proto__ = func. Prototype
    let obj = Object.create(func.prototype);
    // args is an input parameter to the constructor. Since myNew is used here, the input parameter is passed in from myNew
    let result = func.apply(obj, args);
    return Object.prototype.toString.call(result) === '[object Object]' ? result : obj
}
Copy the code

Curry

Currization refers to converting a function that takes multiple arguments to a fixed number of arguments, and then returning a function that takes the rest. The function.length attribute specifies the number of parameters to a function.

function curry(fn) {
    return function recursive(. args) {
        if (fn.length > args.length) {
            return (. rest) = >recursive(... args, ... rest); }else {
            returnfn(... args); }}}Copy the code

6. Function composition compose

Function composition refers to the execution of one function by assigning the returned result as an argument to the next function. Function pipelines are executed from left to right functions, and function combinations are executed from right to left.

function compose(. args) {
  return subArgs= > {
    return args.reverse().reduce((total, func, index) = > {
      returnfunc(total); }, subArgs); }}Copy the code

7. The shock proof function debounce

Anti-shake refers to firing the same event many times over a short period of time, delaying the execution of the function only once after the last event has completed. For example, when a user is entering a user name, the user name needs to be repeatedly verified. In this case, the user experience will be affected. The principle of anti-shake is that a timer is set after an event is triggered. If an event is triggered again during the timer delay, the timer is reset until no event is triggered and the timer is triggered and the corresponding function is executed.

function debounce(func, delay = 200) {
    if (typeoffunc ! = ='function') {
        throw Error('Func must be a function')};let timer = null;
    return function() {
        let context = this;
        let args = arguments;
        if (timer) clearTimeout(timer);
        timer = setTimeout((a)= > {
            func.apply(context, args)
        }, delay);
    };
};
Copy the code

8. Throttle functions

Throttling means executing a function every once in a while. Drip water like an untightened faucet at regular intervals, even if the water in the pipe during this period of time, the faucet will not drop more water. The implementation principle of throttling is that a timer is set after an event is triggered. During the timer delay process, the delay time of the timer does not change even if the event is triggered again. The timer will be reset only after the event is triggered next time.

function throttle(func, delay = 200) {
    if (typeoffunc ! = ='function') {
        throw Error('Func must be a function')};let timer = null;
    return function() {
        let context = this;
        let args = arguments;
        if(! timer) { timer = setTimeout((a)= > {
                timer = null;
                func.apply(context, args);
            }, delay);
        };
    };
};
Copy the code