The article is built on the basis of everyone has already understood the anti – shake

Why did you add it to anti-shakereturn function()

<input id="ooclick" type="button" value="click" />
Copy the code
const btn = document.getElementById("btn");
function cc() {
  console.log("click me ");
}

function debounce(func, wait) {
  return function () {
    // =>为什么用 return
    func();
  };
}
// The following 2 methods are equivalent
btn.addEventListener("click", cc);
btn.addEventListener("click".function (event) {
  cc(event);
});
Copy the code

btn.addEventListener

element.addEventListener(event, function, useCapture)

  1. The first argument is the type of the event (such as ‘click’ or ‘mousedown’)

  2. The second argument is the function we want to call when the event occurs.

    You can also pass an object to the addEventListener as a second argument. When the event is raised, the handleEvent method of that object is called.

    document.body.addEventListener(
      "click",
      {
        handleEvent: function () {
          alert("body clicked"); }},false
    );
    Copy the code

    The use of object as a second argument has one important feature: the function value of the handleEvent property is called only when the event is fired. This means that we change the function value of the handleEvent property so that a different function is called when the event is triggered, which is delayed binding.

    document.body.addEventListener("click", obj, false);
    obj.handleEvent = function () {
      alert("alpha");
    };
    Copy the code
  3. The third parameter is a Boolean value that specifies whether to use event bubbling or event capturing (this parameter is optional, default is false, event bubbling)

    event.stopPropagation(); // Prevent events from bubbling
    event.stopImmediatePropagation(); // Block event capture
    Copy the code

With delayed binding

btn.addEventListener("click", cc);
// Attention!! btn.addEventListener("click", cc()); The CC result is executed directly when binding
btn.addEventListener("click", debounce()); / / debounce () function ()
Copy the code

Here cc is an expression and obj.handleEvent = cc; Result sets that are not immediately executed by methods; The obj. HandleEvent = debounce (); Function debounce()() returns the method exposed in executing the shock proof function (the closure method in return) debounce()

Pay attention to the point

function a() {
  console.log("a");
}
var b = a();
// b becomes the return result set B of an immediately executed function; (b () error)
var b = a;
// b becomes an executable function expression; b(); (b; Nothing, print function)
Copy the code

Set up and clear time managers

Scope and closure

Lexical scope

The first stage of the compiler’s work is called word segmentation, which is the decomposition of a string of characters into lexical units. This concept is fundamental to understanding lexical scope

Simply put, lexical scope is defined at the lexical stage. It is determined by where the variable and block scopes are written when the code is written. Therefore, the scope remains the same when the lexical analyzer processes the code; No matter where a function is called, and no matter how it is called, its lexical scope is determined only by where the function is declared, right

Closures are a difficult and characteristic feature of Javascript, and many advanced applications rely on closures. (Very linguistic)

Little red book

A function that has access to a variable in another function’s scope.

You don ‘t know JS

Closures occur when a function can remember and access its lexical scope, even if the function is executed outside the current lexical scope

Authoritative guide

Function objects can be associated by scope, and variables in the body of a function can be stored in the function scope, which is called a “closure” in the computer science literature. All javascirpt functions are closures

timer

function debounce(func, wait) {
  /** To make closure functions relate to each other, the bridge communication (scope chain) timer is defined outside the closure body so that the closure can access it. So we can define the listener as well as the timer variable btn.addeventListener ("click", debounce()); Each click will only trigger the body of the return function in Debounce (), instead of building the body of the debounce () equivalent to multiple asynchronous subset functions, using the same parent function (like degrees in the tree in the heap) */
  let timer = null;
  return function () {
    /** The ID returned by timer = settimout is no longer unique. The executing functions here are all independent and disjoint, so it cannot be cleared because there is no relation
    // let timer = null;
    clearTimeout(timer);
    timer = setTimeout(function () {
      func();
    }, wait);
  };
}
Copy the code

The clearTimeout() method cancels timeout set by the setTimeout() method. It takes the ID value returned by setTimeout(), which identifies the block of code to cancel deferred execution.

Where are you pointing this

This where are you

const btn = document.getElementById("btn");
function cc() {
  console.log("click me ");
  console.log(this);
}
/ / 1
btn.addEventListener("click", cc);
/ / 2
btn.addEventListener("click".function () {
  console.log(this);
  cc();
});
Copy the code
  1. This in cc refers to the button instance

  2. In addEventListener, this points to the Button instance; This in cc refers to a Windows instance

    Cc.bind (this,..) (a); cc.applay(this,[]); cc.call(this,…)

Join the setTimeout

function debounce(func, wait) {
  let timer;
  return function () {
    let that = this; // Note that this points to
    timer && clearTimeout(timer);
    // Method 1 passes that
    timer = setTimeout(function () {
      func.apply(that, args);
    }, wait);
    // Method 2 arrow function
    timer = setTimeout(() = > {
      func.apply(this, args);
    }, wait);
  };
}
Copy the code

Should we correct the pointing of this and Event objects?

Because if you don’t bind this, you get the classic case of this being lost (pointing to Windows). If you don’t fix the orientation of this, each reference will not find a specific instance, which can lead to unexpected errors

VueComponent({
  data: {return{name:0
  }
})
debounce(function () {
  /** Assuming the vUE environment does not handle this missing this does not refer to the vue instance object */
  this.name === vueComponent.data.name // false
});
Copy the code

How to handle the input parameter??

function debounce(func, wait) {
  let timer;
  return function () {
    let context = this; // Note that this points to
    timer && clearTimeout(timer);
    timer = setTimeout(() = > {
      func.apply(this);
    }, wait);
  };
}
Copy the code

The Arguments object

MDN describes that in javascript, functions are not overloaded, so called overloaded; A function can have multiple function overloading, so Arguments can be used as Arguments. Js does not have function overloading, so it does not matter whether a function is passed or not.

Inside a javascript function, arguments, like an array (not really an array, but a arguments object, again), have a length property that represents the number of arguments passed to the function. The Arguments object is the actual argument to a function in javascript, and the length of the Arguments object is determined by the number of Arguments, not the number of parameters.

Parameters are variables that are stored in the memory space that has been re-created inside functions, but they don’t overlap with the memory space of the Arguments object.

Parameters are variables that are stored in the memory space that has been re-created inside functions, but they don’t overlap with the memory space of the Arguments object.

Parameters are variables that are stored in the memory space that has been re-created inside functions, but they don’t overlap with the memory space of the Arguments object.

Is an array-like object corresponding to the parameters passed to the function. The length of the object is determined by the number of arguments, not the number of parameters. Class array (pseudoclass array) : is the form of an array, has length, but does not have all the methods of an array.

Pay attention to

With the advent of es6 arrow functions, arguments objects are relatively rare, since arrow functions don’t have arguments objects.

Arguments objects are local variables available in all (non-arrow, default) functions;

Arguments objects are local variables available in all (non-arrow, default) functions;

Arguments objects are local variables available in all (non-arrow, default) functions;

You can use arguments objects to refer to function arguments in functions. This object contains each argument passed to the function, the first at index 0. For example, if a function passes three arguments, you can refer to them as follows:

function a(aa = [], bb = 12, cc = "cc") {
  arguments[0]; // undefined
  arguments[1]; // null
  arguments[2]; / / 0
  cc = "Wahaha";
  arguments[2]; //0 is not equal to cc
}
a(undefined.null.0);
Copy the code

Transfer data using Apply Call Bind

function debounce(func, wait) {
  let timer;
  return function () {
    let context = this; // Note that this points to
    let args = arguments; // arguments are stored in
    timer && clearTimeout(timer);
    timer = setTimeout(() = > {
      func.apply(this, args);
      func.call(this. args); func.bind(this. args)(); }, wait); }; }Copy the code