The need for JavaScript to advance

Both react and Vue are js application frameworks. Peel off their shells and see js, so as a front-end chef must master the big spoon of JS, in order to cook a good dish

Whether it’s for self-improvement or for an interview, the following handwriting functions are essential for every front-end programmer to master

1. Write apply, call, bind by hand

Each Function object has the apply(), call(), and bind() methods, which can be used to call the Function in a specific scope.Copy the code
The similarities and differences between apply, call and bind
If this is null or undefined, it points to window. If this is null or undefined, it points to window. Bind can be called multiple times. 3. Apply and call run the function after this is pointed to, while bind returns the function after the bindingCopy the code
Reference code for the Apply implementation
/** * write apply */
window.name='gy' // Global variables
let obj={
  name:'ckx'
}

var func=function(b,c){
  console.log(`this=`.this)
  console.log(this.name,b,c)
  return 1
}

func('24'.'hz')   // gy 24 hz

func.apply(obj,['24'.'hz']) // ckx 24 hz

let newObj={
  name:'xmx'.age:24
}
Function.prototype.myApply=function(base,args){
  // 1. If the pointer is null or undefined, the pointer is window
  base=base || window
  // 2. Assign the function referred to by this to an attribute of the base object
  base.fn=this
  // 3. When base.fn is called, the function in fn refers to the base object
  letresult=base.fn(... args)// 4. Delete the base fn attribute
  delete base.fn
  // 5. Return result
  return  result
}

func.myApply(newObj,['55'.'yw']) // xmx 55 yw
Copy the code
The apply code executes the effect

Call implementation reference code
/** * write call */
window.name='gy' // Global variables
let obj={
  name:'ckx'
}

var func=function(b,c){
  console.log(`this=`.this)
  console.log(this.name,b,c)
  return 1
}

func('24'.'hz')   // gy 24 hz

func.call(obj,'24'.'hz') // ckx 24 hz

let newObj={
  name:'xmx'.age:24
}
// Call and apply need to pay attention to the format of the arguments
Function.prototype.myCall=function(base,... args){
  // 1. If the pointer is null or undefined, the pointer is window
  base=base || window
  // 2. Assign the function referred to by this to an attribute of the base object
  base.fn=this
  // 3. When base.fn is called, the function in fn refers to the base object
  letresult=base.fn(... args)// 4. Delete the base fn attribute
  delete base.fn
  // 5. Return result
  return  result
}

func.myCall(newObj,'55'.'yw') // xmx 55 yw
Copy the code
Call code execution effect

Reference code for the bind implementation
/** * write bind */
window.name = "gy"; // Global variables
let obj = {
  name: "ckx"};var func = function (b, c,d) {
  console.log(`this=`.this);
  console.log(this.name, b, c,d);
  return 1;
};

func("24"."hz".26); // gy 24 hz 26

let funcRes = func.bind(obj, "24"."hz");
funcRes(24);  // ckx 24 hz 24

let newObj = {
  name: "xmx".age: 24};// Note that bind returns the function to bind and can pass arguments multiple times
Function.prototype.myBind = function (base, ... args1) {
  return (. args2) = > {
    // 1. If the pointer is null or undefined, the pointer is window
    base = base || window;
    // 2. Assign the function referred to by this to an attribute of the base object
    base.fn = this;
    // 3. When base.fn is called, the function in fn refers to the base object
    letresult = base.fn(... args1,... args2);// 4. Delete the base fn attribute
    delete base.fn;
    // 5. Return result
    return result;
  };
};
let myfuncRes=func.myBind(newObj, "55"."yw")
myfuncRes(24) // xmx 55 yw 24
Copy the code
Bind code execution effect

2. Write a new

What is done when the new keyword is executed
1. Create a new object. 2. Link the new object to the constructor with a prototype chain. Assign the constructor's this to the new object and execute the constructor's code assignment 4. Return the newly created object if the constructor does not return an object otherwise return the object returned by the constructorCopy the code
Handwritten new reference code
/*** * write the new keyword */

function Person(name,age) {
  this.name = name;
}
Person.prototype.getName = function () {
  return this.name;
};
let a = new Person('gy');
console.log(a);
console.log(a.getName());


const myNew = (Func, ... args) = > {
  let newObj = {};
  newObj.__proto__=Func.prototype
  let result=Func.apply(newObj,args)
  return  typeof result == Object ? result: newObj
};
let b = myNew(Person,'gy1')
console.log(b);
console.log(b.getName());
Copy the code
Code execution result reference diagram

Prototype chain diagram

3. The handwritten instanceof

Typeof can determine the base datatype, but null returns object that does not recognize the reference datatype. Instanceof can accurately determine the reference datatype but does not recognize the base datatype Instanceof is the prototype chain used to check whether the constructor's prototype appears on an instance objectCopy the code
Reference code
/** * write instanceof */
let obj= { label:'gy' }
let arr= ['hello']

let result = obj instanceof Object
let result1 = arr instanceof Array
let result2 = arr instanceof Object
let result3 = obj instanceof Array

console.log('result=',result )
console.log('result1=',result1 )
console.log('result2=',result2 )
console.log('result3=',result3 )

const myInstanceof = (left,right) = >{
    if(typeofleft ! ='object' || left == null ) return false
    let proto= Object.getPrototypeOf(left)
    while(true) {if(proto==null) return false
        if(proto==right.prototype) return true
        proto=Object.getPrototypeOf(proto)
    }
}

const myResult= myInstanceof(obj,Object)
const myResult1= myInstanceof(arr,Array)
const myResult2= myInstanceof(arr,Object)
const myResult3= myInstanceof(obj,Array)

console.log('myRsult=',myResult )
console.log('myResult1=',myResult1 )
console.log('myResult2=',myResult2 )
console.log('myResult3=',myResult3 )
Copy the code
Screenshot of code execution result

To print the result according to the code above, note: Everything is an object, including arrays, so if there's a variable arrOrObj that could be array or object and if you use instanceof, you have to check whether it's an array first, Otherwise arrOrObj instanceof Object must be true and cannot distinguish array from Object

4. Handwritten anti-shake and throttling

If the event is triggered continuously, the callback will be executed after n seconds delay. If the event is triggered again before n seconds delay, the callback will be executed after N seconds delay. If the event starts again before n seconds delay, the timer will not be resetCopy the code
Usage scenarios for both

Anti-shake may be used for unpredictable user initiatives, such as users entering content to dynamically search for results on the server. The speed at which users type is unpredictable and irregular.

Throttling may be used for some non-user active behaviors or predictable user active behaviors, such as sending buried request when users slide merchandise window, sliding fixed height is known logic, with regularity.

The throttleandImage stabilizationIt’s also an application of closures

Handwritten anti – shake code reference
/*** * Handwriting stabilization */
const debounce = (func, delay) = > {
  let timer = null;
  return function (. args) {
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }
    timer = setTimeout(() = > {
      func(args);
    }, delay);
  };
};
const getfn = (data) = > {
  console.log(data);
};
debounce(getfn, 2000) ("gy");
Copy the code
Handwritten anti-shake code execution results

Handwritten throttling
/*** * handwritten throttling * here only need to note that the timer will not be cleared when different from anti-shake */
const throttle = (func, delay) = > {
  let flag = false;
  return function (. args) {
    if (flag)  return
    flag=true
    setTimeout(() = > {
      func(args);
      flag=false
    }, delay);
  };
};
const getfn = (data) = > {
  console.log(data);
};
throttle(getfn, 2000) ("gy");
Copy the code

5. Implement Ajax manually

Asynchronous JavaScript + XML is the name of AJAX, and the most important is XHR(XMLHttpRequest). XMLHttpRequest retrieves data by requesting a specific URL without refreshing the page.Copy the code
Prerequisites for implementation
  1. XMLHttpRequest() is a constructor

  2. XMLHttpRequest. Onreadystatechange status code changes trigger events (all browsers support)

  3. XMLHttpRequest. ReadyState request status code

  1. XMLHttpRequest.statusResponse status code Returns the standard HTTP status code

  1. Additional request response parameters

    XMLHttpRequest. The response to this is the whole response entity XMLHttpRequest. The responseText return ` DOMString ` XMLHttpRequest. A timeout timeout Xmlhttprequest. upload Upload progressCopy the code
  2. Take a look at the common methods

open()

// method/url is required xhr.open(method, url, async, user, password);Copy the code

send()

// Can be Blob, BufferSource (en-us), FormData, URLSearchParams, or USVString objects. XMLHttpRequest.send(body);Copy the code

setRequestHeader()

XMLHttpRequest.setRequestHeader(header, value); / / such as XMLHttpRequest. SetRequestHeader (" the content-type ", "application/x - WWW - form - urlencoded");Copy the code
Implement Ajax based on the above API
1. Construct a request XMLHttpRequest 2. Initialize a request open 3. Onreadystatechange 4. Send the requestCopy the code
/** * Write an Ajax */
const myAjax =(url,methods,header,success,error) = >{
    // Create a request
    let request=new XMLHttpRequest()
    // Set the request header
    for (const key in header) {
        request.setRequestHeader(key,header[key])
    }
    // Initialize the request
    request.open(methods,url)
    // Send the request
    request.send()
    // Listen for request onreadyStatechange
    request.onreadystatechange =function(){
        if(request.readyState==4) {if(request.status==200){
                success(request.response)
            }else {
                error()
            }
        }
    }
}
Copy the code

conclusion

Better ideas and other must-have handwriting features are welcomeCopy the code