[Front end] Catch it all in one go-8 handwritten codes that must be met in front-end advancement and interviews

[Front end] Catch it all in one go-8 handwritten codes that must be met in front-end advancement and interviews

1 Handwritten Promise series

In the Promise of study, also written before relevant share articles, please see the "front-end [white] started from the perspective of Promise, Async/await and Shredded Code" .

1.1 Promise.all

//Handwritten promise.all Promise .prototype._all = promiseList => { //When the input is a promise list const len = promiseList.length; const result = []; let count = 0 ; // return new Promise ( ( resolve,reject )=> { //Loop through the promise events in the promise list for ( let i = 0 ; i <len; i++){ //Traverse to the i-th promise event and determine whether the event succeeded or failed promiseList[ i].then( data => { result[i] = data; count++; //When traversing to the last promise, the length of the result array is the same as the length of the promise list, indicating success count === len && resolve(result); }, error => { return reject(error); }) } }) } Copy code

1.2 Promise.race

//Handwritten promise.race Promise .prototype._race = promiseList => { const len = promiseList.length; return new Promise ( ( resolve,reject )=> { //Loop through the promise events in the promise list for ( let i = 0 ; i <len; i++){ promiseList[i]().then( data => { return resolve(data); }, error => { return reject(error); }) } }) } Copy code

1.3 Promise.finally

Promise .prototype._finally = function ( promiseFunc ) { return this .then( data => Promise .resolve(promiseFunc()).then( data => data) , error => Promise .reject(promiseFunc()).then( error => { throw error})) } Copy code

2 Handwriting Aysnc/Await

function asyncGenertor ( genFunc ) { return new Promise ( ( resolve,reject )=> { //Generate an iterator const gen = genFunc(); const step = ( type,args )=> { let next; try { next = gen[type](args); } catch (e){ return reject(e); } //Get the values of done and value from next const (done,value) = next; //If the state of the iterator is true if (done) return resolve(value); Promise .resolve(value).then( val = > step( "next" ,val), err => step( "throw" ,err) ) } step( "next" ); }) } Copy code

3 Deep copy

Deep copy: Copy all attribute values and the memory space of the value pointed to by the attribute address.

3.1 Deep copy of missing reference

When an object is encountered, a new object is opened, and then the attribute values of the second-level source object are completely copied to this newly opened object.

//Deep copy with missing reference function deepClone ( obj ) { //Determine whether the type of obj is object type if (!obj && typeof obj !== "object" ) return ; //Determine whether the object is an array type or an object type let newObj = Array .isArray(obj)? []: {}; //Traverse the key-value pairs of obj for ( const [key,value] of Object .entries(obj)){ newObj[key] = typeof value === "string" ? deepClone(value): value; }; return newObj; } Copy code

3.2 Deep copy of the ultimate solution (stack and depth-first thinking)

The idea is: to introduce an array

uniqueList
Used to store the copied array, each time the loop traverses, first determine whether the object is in
uniqueList
If it is, the copy logic will not be executed.

function deepCopy ( obj ) { //used to remove duplicates const uniqueList = []; //set the root node let root = {}; //traverse the array const loopList = [{ parent : root, key : undefined , data : obj }]; //Traverse the loop while (loopList.length){ //Depth first-take out the last element of the array const {parent,key,data} = loopList.pop(); //Initialize the assignment target, copy to when key--undefined Parent element, otherwise copy to child element let result = parent; if ( typeof key !== "undefined" ) result = parent[key] = {}; //When the data already exists let uniqueData = uniqueList.find( item => item.source === data); if (uniqueData){ parent[key] = uniqueData.target; //Interrupt this cycle continue ; } //When the data does not exist //Save the source data, and copy the corresponding reference in the data uniqueList.push({ source :data, target :result }); //Traverse the data for ( let k in data){ if (data.hasOwnProperty(k)){ typeof data[k] === "object" ? //next loop loopList.push({ parent :result, key :k, data :data[k] }) : result[k] = data[k]; } } } return root; } Copy code

4 Handwriting a singleton pattern

Singleton mode: Ensure that a class has only one instance, and provide a global access point to access it. The implementation method is generally to first determine whether the instance exists, if it exists, return directly, if it does not exist, create it and return.

//Create a singleton object, use closure const getSingle = function ( func ) { let result; return function () { return result || (result = func.apply( this , arguments )); } } //Use Proxy to intercept const proxy = function ( func ) { let reuslt; const handler = { construct : function () { if (!result) result = Reflect .construct(func, arguments ); return result; } } return new Proxy (func,hendler); } Copy code

5 encapsulate an ajax function by hand

/* Encapsulate your own ajax function Parameter 1: {string} method request method Parameter 2: {string} url request address Parameter 2: {Object} params request parameters Parameter 3: {function} done Callback function to be executed after the request is completed */ function ajax ( method,url,params,done ) { //1. Create xhr object, compatible with writing let xhr = window .XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject( "Microsoft.XMLHTTP" ); //Convert method to uppercase method = method.toUpperCase(); //Parameter splicing let newParams = []; for ( let key in params){ newParams.push( ` ${key} = ${params[k]} ` ); } let str = newParams.join( "&" ); //Determine the request method if (method === "GET" ) url += `? ${str} ` ; //Open the request method xhr.open(method,url); let data = null ; if (method === "POST" ){ //Set the request header xhr.setRequestHeader(( "Content-Type" , "application/x-www-form-urlencoded" )); data = str; } xhr.send(data); //Specify the xhr state change event processing function //Execute the callback function xhr.onreadystatechange = function () { if ( this .readyState === 4 ) done( JSON .parse(xhr.responseText)); } } Copy code

6 Handwriting "Anti-shake" and "Throttling"

In the study of "Anti-shake" and "Throttling", I have also written related sharing articles before. Please refer to "One Net-The "Anti-shake" and "Throttling" Methods of Front End . "

6.1 Anti-shake

/* func: The function to be processed for anti-shake processing delay: the time to be delayed immediate: whether to use immediate execution true immediate execution false non-immediate execution */ function debounce ( func,delay,immediate ) { let timeout; //Timer return function ( arguments ) { //Determine whether the timer exists, clear it if it exists, and restart the timer count if (timeout) clearTimeout (timeout ); Stabilizer the stabilizer//judgment is executed immediately or not immediately executed IF (immediate) { //perform immediately const in Flag = timeout;! //here negate operation timeout = the setTimeout ( () => { timeout = null ; },delay); //The function will be executed immediately after the event is triggered, and then the effect of the function can be continued without triggering the event within n seconds. if (flag) func.call( this , arguments ); } else { //Non-immediate execution timeout = setTimeout ( ()=> { func.call( this , arguments ); },delay) } } } Copy code

6.2 Throttling

//Throttle-timer version function throttle ( func, delay ) { let timeout; //Define a timer mark return function ( arguments ) { //Determine whether there is a timer if (!timeout){ //Create one Timer timeout = setTimeout ( ()=> { //The delay interval clears the timer clearTimeout (timeout); func.call( this , arguments ); },delay) } } } Copy code

7 Handwriting apply, bind, call

7.1 apply

  • The parameters passed to the function are handled differently, and the other parts are the same as call.
  • apply accepts the second parameter as an array-like object, here we use the method of judging whether it is an array-like object in the "JavaScript Definitive Guide".
Function .prototype._apply = function ( context ) { if (context === null || context === undefined) { context = window //The this value specified as null and undefined will automatically point to the global object (window in the browser) } else { context = Object (context) //this value of the original value (number, string, boolean) will point to the instance object of the original value } //JavaScript function isArrayLike(o) { if (o && //o null undefined typeof o === 'object' && //o isFinite(o.length) && //o.length o.length >= 0 && //o.length o.length === Math.floor(o.length) && //o.length o.length < 4294967296) //o.length < 2^32 return true else return false } const specialPrototype = Symbol(' Symbol') // context[specialPrototype] = this; // this context let args = arguments[1]; // let result // if (args) { // if (!Array.isArray(args) && !isArrayLike(args)) { throw new TypeError('myApply '); } else { args = Array.from(args) // result = context[specialPrototype](...args); // } } else { result = context[specialPrototype](); // } delete context[specialPrototype]; // return result; // };

7.2 bind

  • :

    • Object.create prototype fToBind
    • new instanceof new context
    • this+
Function.prototype._bind = function (objThis, ...params) { const thisFn = this; // params( ) // secondParams let fToBind = function (...secondParams) { const isNew = this instanceof fToBind //this fToBind fToBind new const context = isNew ? this : Object(objThis) //new this , objThis return thisFn.call(context, ...params, ...secondParams); // call this , }; if (thisFn.prototype) { // prototype fToBind prototype fToBind.prototype = Object.create(thisFn.prototype); } return fToBind; // };

7.3 call

  • call , this
  • context , this context
Function.prototype._call = function (context, ...arr) { if (context === null || context === undefined) { // null undefined this ( window) context = window } else { context = Object(context) // this } const specialPrototype = Symbol(' Symbol') // context[specialPrototype] = this; // this context let result = context[specialPrototype](...arr); // delete context[specialPrototype]; // return result; // };

8

8.1

function fatherUser(username, password) { let _password = password this.username = username fatherUser.prototype.login = function () { console.log(this.username + ' ' + _password) } } function sonUser(username, password) { fatherUser.call(this, username, password) this.articles = 3 // } const yichuanUser = new sonUser('yichuan', 'xxx') console.log(yichuanUser.username) //yichuan console.log(yichuanUser.username) //xxx console.log(yichuanUser.login()) //TypeError: yichuanUser.login is not a function

8.2

function fatherUser(username, password) { let _password = password this.username = username fatherUser.prototype.login = function () { console.log(this.username + ' fatherUser ' + _password) } } function sonUser(username, password) { fatherUser.call(this, username, password) // fatherUser this.articles = 3 // } = sonUser.prototype new new fatherUser (); //perform fatherUser second constructor const yichuanUser = new new sonUser ( 'Yichuan' , 'XXX' ) copying the code

8.3 Parasitic combinatorial inheritance

The above inheritance method is flawed, so just write this method.

function Parent() { this .name = 'parent' ; } function Child () { Parent.call( this ); this .type = 'children' ; } Child.prototype = Object .create(Parent.prototype); Child.prototype.constructor = Child; Copy code

Reference article

"Summary of JavaScript Skills for Advanced Frontends"

"Js basics-the interviewer wants to know how well you understand call, apply, bind? [Don t Look at Regret Series]"

Write at the end

I am a front-end Xiaocai. Thank you for reading. I will continue to share more excellent articles with you. This article refers to a large number of books and articles. If there are errors or omissions, I hope I can correct them.