This article has participated in the activity of “New person creation Ceremony”, and started the road of digging gold creation together.
preface
As a front-end development, JS is the top priority, code ability is undoubtedly very important, this article can help you expand and consolidate their JS foundation, in the work can also be used for handwriting requirements, such as deep copy, anti-shaking throttling can be directly used in the future project, improve the efficiency of project development.
While reading, we should know exactly what it is doing, why it is written this way, and whether it can be written better. After reading, you can also use the front-end tools to write for better understanding and use.
1 Handwritten array deduplication
Implement a method that returns a new array
Set function uniqueArr(arr) {return [...new set (arr)]; } // Use indexOf function uniqueArr(arr) {const res = []; for (let i = 0; i < arr.length; i++) { if (res.indexOf(arr[i]) === -1){ res.push(arr[i]); } } return res; } // console.log(uniqueArr([1, 2, 3, 4, 1, 2]));Copy the code
2 Handwriting array flattening
Implements a method to turn a multidimensional array into a one-dimensional array
function flatter(arr) { if (! arr.length) return; return arr.reduce( (pre, cur) => Array.isArray(cur) ? [...pre, ...flatter(cur)] : [...pre, cur], [] ); } // console.log(flatter([1, 2, [1, [2, 3, [4, 5, [6]]]]]));Copy the code
3. Handwritten data type judgment:
The following three methods can be used for data type judgment, but all of them have certain limitations, so the type judgment method will be rewritten in the actual development process of the project.
Typeof: Undefined, Boolean, Number, String, Symbol, Function, etc. Typeof returns the basic typeof a variable.
Instanceof: Complex reference data types can be accurately identified. Instanceof returns a Boolean value.
Object. The prototype. ToString. Call () : this method is invoked, the unity of the format “[Object] Xxx” string.
function typeOf(obj) {
let res = Object.prototype.toString.call(obj).split(' ')[1]
res = res.substring(0, res.length - 1).toLowerCase()
return res
}
typeOf([]) // 'array'
typeOf({}) // 'object'
typeOf(new Date) // 'date'
Copy the code
4. Copy by hand in light and dark
Shallow copy
For reference types, a new object is generated directly from the original object, and both the original object and the new object point to the memory address in the heap, so that changes to the new object or the original object affect each other.
function assign2(target, ... source) { if (target == null) { return target } let ret = Object(target) source.forEach(function(obj) { if (obj ! = null) { for (let key in obj) { if (obj.hasOwnProperty(key)) { ret[key] = obj[key] } } } }) return ret }Copy the code
Deep copy
For reference types, we use the deep-copy implementation to create our own memory space in the new object heap, so that changes to the new object or the original object do not affect each other.
function copyObj(obj){ var cloneObj; // Copy if(obj&&typeof obj! =='object'){cloneObj=obj; } else if(obj&&typeof obj==='object'){cloneObj= array.isarray (obj)? [] : {}; For (let key in obj){if(obj. HasOwnProperty (key)){if(obj[key]&&typeof obj[key]==='object') {// If (obj[key] ==='object') CloneObj [key] = copyObj(obj[key]); } else{cloneObj[key]=obj[key]; } } } } return cloneObj; }Copy the code
5. Handwritten anti-shake throttling:
Image stabilization
The purpose of both stabilization and throttling is to prevent multiple calls to the function. The difference is that if a user fires the function all the time and the interval is shorter than the set time, the function will only be called once in the case of stabilization, while the function will be called once in the case of throttling.
Stabilization scenarios: according to the search content matching data, but if the user input a series of characters quickly, hypothesis is 10 characters, will be triggered in a flash of 10 times the request, what we want is the user when it stop input to trigger a query request, this function if you can help us. Its purpose is to not execute the function while it is firing, and to wait until some time after the last firing has finished. For example, after the input is complete, the interface search returns the data.
function debounce(func, wait) { var timeout; return function () { var context = this; var args = arguments; clearTimeout(timeout) timeout = setTimeout(function(){ func.apply(context, args) }, wait); }}Copy the code
The throttle
Throttling application scenario: When scrolling the browser scrollbar, update some layout content on the page or call an interface in the background to query content. Similarly, if the frequency of function calls is not limited, then we may scroll the scrollbar for N times. This time, however, the situation is different. Instead of executing a function after a certain period of time, we need to execute a function at a certain interval to avoid excessive execution of the function.
function throttle(func, wait) { var context, args; var previous = 0; return function() { var now = +new Date(); context = this; args = arguments; if (now - previous > wait) { func.apply(context, args); previous = now; }}}Copy the code
6. Write the new keyword by hand
The new operator is used to create instances of user-defined object types or built-in objects with constructors.
function myNew(fn, ... Args) {// Create a new object const obj = {}; // The __proto__ attribute of the new object points to the constructor's prototype object obj.__proto__ = fn.prototype; Apply (obj, args) return typeof result === "object"? result : obj }Copy the code
7. Three methods of handwriting function prototype:
call
Call calls a function with a specified this value and one or more arguments.
Implementation notes: This may be passed null; Pass in an unfixed number of arguments; A function may have a return value;
Function.prototype.call2 = function (context) {
var context = context || window;
context.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
var result = eval('context.fn(' + args +')');
delete context.fn
return result;
}
Copy the code
apply
Apply is the same as call, except that call passes in an unlimited number of arguments, whereas apply passes in an array.
Implementation notes: This may be passed null; Pass an array; A function may have a return value;
Function.prototype.apply2 = function (context, arr) { var context = context || window; context.fn = this; var result; if (! arr) { result = context.fn(); } else { var args = []; for (var i = 0, len = arr.length; i < len; i++) { args.push('arr[' + i + ']'); } result = eval('context.fn(' + args + ')') } delete context.fn return result; }Copy the code
bind
The bind method creates a new function. When bind() is called, this of the new function is specified as the first argument to bind(), and the remaining arguments are used as arguments to the new function.
Bind () can pass multiple arguments in addition to this; New functions created by Bing may pass in multiple arguments; New functions may be called as constructors; A function may have a return value;
Function.prototype.bind2 = function (context) {
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {};
var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
}
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
}
Copy the code
8. Written Promise
Promise.all
Promise.all can wrap multiple Promise instances into a new Promise instance. Also, success and failure return different values, with success returning an array of results and failure returning the first rejected state.
Promise.all = function(promiseArr) { let index = 0, result = [] return new Promise((resolve, reject) => { promiseArr.forEach((p, i) => { Promise.resolve(p).then(val => { index++ result[i] = val if (index === promiseArr.length) { resolve(result) } }, err => { reject(err) }) }) }) }Copy the code
Promise.race
Promse.race is a race, which means that a Promise. Race ([P1, P2, P3]) returns the fastest result, regardless of whether the result itself is a success or a failure.
Promise.race = function(promiseArr) {
return new Promise((resolve, reject) => {
promiseArr.forEach(p => {
Promise.resolve(p).then(val => {
resolve(val)
}, err => {
rejecte(err)
})
})
})
}
Copy the code
recommended
If you want to continue learning about browsers, you can watch another article by me on juejin.
If you want to continue to learn the principles of CSS, you can watch the author of another article (interview treasure guide) CSS chapter – Nuggets (juejin. Cn)
If you want to continue to learn the Vue principle of readers, you can watch another article by the author [interview treasure guide] high frequency front end questions of Vue principle of readers – nuggets (juejin. Cn)
If you want to continue to learn the JS principle of readers, you can watch the author of another article [interview treasure guide] high frequency front end questions of JavaScript principle – nuggets (juejin. Cn)
conclusion
This article is the author’s personal study notes, if there are fallacies, please inform, thank you! If this article has been helpful to you, please click the “like” button. Your support is my motivation to keep updating.