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 throttle
andImage stabilization
It’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
-
XMLHttpRequest() is a constructor
-
XMLHttpRequest. Onreadystatechange status code changes trigger events (all browsers support)
-
XMLHttpRequest. ReadyState request status code
XMLHttpRequest.status
Response status code Returns the standard HTTP status code
-
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
-
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