🎄 preface
This article mainly summarizes the handwritten questions in 2021, which are from the front end of the year and the autumn entrance examination. The topic comes from the front end of Niu Kwai network. The statistical time is from the beginning of March to the end of October. The 15 companies came from Ali, Tencent, Baidu, bytes, USA, Jingdong, fast hands and many spells, and made a simple frequency division.
-
⭐⭐⭐⭐⭐: 10 in 15 company interviews+
-
⭐⭐⭐⭐: 5-10 in 15 formula interviews
-
⭐⭐⭐: 3-5 in 15 company interviews
-
No star: 1-2
🌟 promise
Implement promise
Frequency of investigation:( ⭐⭐⭐⭐⭐)
Reference code [1]
Implement promise all
Frequency of investigation:( ⭐⭐⭐⭐⭐)
function PromiseAll(promises){ return new Promise((resolve, reject)=>{ if(!Array.isArray(promises)){ throw new TypeError("promises must be an array") } let result = [] let count = 0 promises.forEach((promise, index) => { promise.then((res)=>{ result[index] = res count++ count === promises.length && resolve(result) }, (err)=>{ reject(err) }) }) }) } Copy code
Implement promise finally
Frequency of investigation:( ⭐⭐⭐⭐⭐)
Promise.prototype.finally = function (cb) { return this.then(function (value) { return Promise.resolve(cb()).then(function () { return value }) }, function (err) { return Promise.resolve(cb()).then(function () { throw err }) }) } Copy code
Implement promise allSettled
Frequency of investigation:( ⭐⭐⭐⭐)
function allSettled(promises) { if (promises.length === 0) return Promise.resolve([]) const _promises = promises.map( item => item instanceof Promise ? item : Promise.resolve(item) ) return new Promise((resolve, reject) => { const result = [] let unSettledPromiseCount = _promises.length _promises.forEach((promise, index) => { promise.then((value) => { result[index] = { status: 'fulfilled', value } unSettledPromiseCount -= 1 // resolve after all are settled if (unSettledPromiseCount === 0) { resolve(result) } }, (reason) => { result[index] = { status: 'rejected', reason } unSettledPromiseCount -= 1 // resolve after all are settled if (unSettledPromiseCount === 0) { resolve(result) } }) }) }) } Copy code
Implement promise race
Frequency of investigation:( ⭐⭐⭐)
Promise.race = function(promiseArr) { return new Promise((resolve, reject) => { promiseArr.forEach(p => { Promise.resolve(p).then(val => { resolve(val) }, err => { rejecte(err) }) }) }) } Copy code
Let's talk about how to execute multiple promises serially
Reference code [2]
promise.any
Promise.any = function(promiseArr) { let index = 0 return new Promise((resolve, reject) => { if (promiseArr.length === 0) return promiseArr.forEach((p, i) => { Promise.resolve(p).then(val => { resolve(val) }, err => { index++ if (index === promiseArr.length) { reject(new AggregateError('All promises were rejected')) } }) }) }) } Copy code
resolve
Promise.resolve = function(value) { if(value instanceof Promise){ return value } return new Promise(resolve => resolve(value)) } Copy code
reject
Promise.reject = function(reason) { return new Promise((resolve, reject) => reject(reason)) } Copy code
🐳 Array chapter
Array de duplication
Frequency of investigation:( ⭐⭐⭐⭐⭐)
Use dual , for , and , splice
function unique(arr){ for(var i=0; i<arr.length; i++){ for(var j=i+1; j<arr.length; j++){ if(arr[i]==arr[j]){ //The first is equivalent to the second, and the splice method deletes the second arr.splice(j,1); //After deletion, pay attention to callback j j--; } } } return arr; } Copy code
Add a new array using , indexOf , or , includes ,
//Use indexof function unique(arr) { var uniqueArr = []; //New array for (let i = 0; i < arr.length; i++) { if (uniqueArr.indexOf(arr[i]) === -1) { //indexof returns - 1, indicating that the element does not exist in the new array uniqueArr.push(arr[i])//If there are no elements in the new array, push them in } } return uniqueArr; } //Use includes function unique(arr) { var uniqueArr = []; for (let i = 0; i < arr.length; i++) { //includes detects whether the array has a value if (!uniqueArr.includes(arr[i])) { uniqueArr.push(arr[i])// } } return uniqueArr; } Copy code
After sort # sorting, use the idea of fast and slow pointers
function unique(arr) { arr.sort((a, b) => a - b); var slow = 1, fast = 1; while (fast < arr.length) { if (arr[fast] != arr[fast - 1]) { arr[slow ++] = arr[fast]; } ++ fast; } arr.length = slow; return arr; } Copy code
The sort() method is used to sort from small to large (return a new array). If the callback function does not contain the above callback in its parameters, the sorting error will occur when there are two or more digits (if omitted, the elements will be sorted according to the Unicode position of each character of the converted string. The two digits will be calculated by changing to a string with a length of two).
ES6 # provides # Set # de duplication
function unique(arr) { const result = new Set(arr); return [...result]; //Use the extension operator to convert the Set data structure to an array } Copy code
Elements in Set , only appear once, that is, elements in Set , are unique.
Use a hash table to store whether an element appears (ES6 # map provided)
function unique(arr) { let map = new Map(); let uniqueArr = new Array(); //Arrays are used to return results for (let i = 0; i < arr.length; i++) { if(map.has(arr[i])) { //If there is this key value map.set(arr[i], true); } else { map.set(arr[i], false); //If there is no key value uniqueArr.push(arr[i]); } } return uniqueArr ; } Copy code
Map} objects hold key value pairs, similar to objects. However, the key of {map} can be of any type, and the key of an object can only be of string type.
If there are only numbers in the array, you can also use ordinary objects as hash tables.
filter} indexOf
function unique(arr) { return arr.filter(function (item, index, arr) { //Current element, the first index in the original array = = the current index value, otherwise the current element is returned //If it is not, it will prove to be a duplicate, so it will be discarded return arr.indexOf(item) === index; }) } Copy code
There may be questions here. Let me give an example:
const arr = [1,1,2,1,3] arr.indexOf(arr[0]) === 0 //1. First appearance of arr.indexOf(arr[1]) !== 1 //Note 1 has appeared before Copy code
reduce} includes
function unique(arr){ let uniqueArr = arr.reduce((acc,cur)=>{ if(!acc.includes(cur)){ acc.push(cur); } return acc; },[]) //[] is the initial value of the first parameter of the callback function return uniqueArr } Copy code
Flatten arrays
Frequency of investigation:( ⭐⭐⭐)
Reference code [3]
forEach
Frequency of investigation:( ⭐⭐⭐)
Array.prototype.myForEach = function (callbackFn) { //Judge whether this is legal if (this === null || this === undefined) { throw new TypeError("Cannot read property 'myForEach' of null"); } //Judge whether callbackFn is legal if (Object.prototype.toString.call(callbackFn) !== "[object Function]") { throw new TypeError(callbackFn + ' is not a function') } //Get the array object of the execution method and the passed in this object var _arr = this, thisArg = arguments[1] || window; for (var i = 0; i < _arr.length; i++) { //Execute callback function callbackFn.call(thisArg, _arr[i], i, _arr); } } Copy code
reduce
Frequency of investigation:( ⭐⭐⭐)
Array.prototype.myReduce = function(callbackFn) { var _arr = this, accumulator = arguments[1]; var i = 0; //Determine whether to pass in the initial value if (accumulator === undefined) { //If you call reduce for an empty array without an initial value, an error will be reported if (_arr.length === 0) { throw new Error('initVal and Array.length>0 need one') } //The initial value is assigned to the first element of the array accumulator = _arr[i]; i++; } for (; i<_arr.length; i++) { //The calculation result is assigned to the initial value accumulator = callbackFn(accumulator, _arr[i], i, _arr) } return accumulator; } Copy code
map
Array.prototype.myMap = function(callbackFn) { var _arr = this, thisArg = arguments[1] || window, res = []; for (var i = 0; i<_arr.length; i++) { //Store operation results res.push(callbackFn.call(thisArg, _arr[i], i, _arr)); } return res; } Copy code
filter
Array.prototype.myFilter = function(callbackFn) { var _arr = this, thisArg = arguments[1] || window, res = []; for (var i = 0; i<_arr.length; i++) { //The callback function executes as true if (callbackFn.call(thisArg, _arr[i], i, _arr)) { res.push(_arr[i]); } } return res; } Copy code
every
Array.prototype.myEvery = function(callbackFn) { var _arr = this, thisArg = arguments[1] || window; //The start identity value is true //If the callback returns false, it returns false directly //If the loop is completed, it means that the return value of all callbacks is true and the final result is true var flag = true; for (var i = 0; i<_arr.length; i++) { //The callback function is executed as false, and the function is interrupted if (!callbackFn.call(thisArg, _arr[i], i, _arr)) { return false; } } return flag; } Copy code
some
Array.prototype.mySome = function(callbackFn) { var _arr = this, thisArg = arguments[1] || window; //The start identity value is false //If the callback returns true, return true directly //If the loop is completed, it means that the return value of all callbacks is false and the final result is false var flag = false; for (var i = 0; i<_arr.length; i++) { //The callback function is executed as false, and the function is interrupted if (callbackFn.call(thisArg, _arr[i], i, _arr)) { return true; } } return flag; } Copy code
find/findIndex
Array.prototype.myFind = function(callbackFn) { var _arr = this, thisArg = arguments[1] || window; //If the callback returns true, the array element is returned directly //If the loop is completed, it means that the return value of all callbacks is false and the final result is undefined for (var i = 0; i<_arr.length; i++) { //The callback function is executed as false, and the function is interrupted if (callbackFn.call(thisArg, _arr[i], i, _arr)) { return _arr[i]; } } return undefined; } Copy code
indexOf
function indexOf(findVal, beginIndex = 0) { if (this.length < 1 || beginIndex > findVal.length) { return -1; } if (!findVal) { return 0; } beginIndex = beginIndex <= 0 ? 0 : beginIndex; for (let i = beginIndex; i < this.length; i++) { if (this[i] == findVal) return i; } return -1; } Copy code
Implement sort
Reference code [4]
🌊 Anti shake throttle
Implementation of debounce function
Frequency of investigation:( ⭐⭐⭐⭐⭐)
function debounce(func, wait, immediate) { var timeout, result; var debounced = function () { var context = this; var args = arguments; if (timeout) clearTimeout(timeout); if (immediate) { //If it has been executed, it will not be executed again var callNow = !timeout; timeout = setTimeout(function(){ timeout = null; }, wait) if (callNow) result = func.apply(context, args) } else { timeout = setTimeout(function(){ result = func.apply(context, args) }, wait); } return result; }; debounced.cancel = function() { clearTimeout(timeout); timeout = null; }; return debounced; } Copy code
Implement throttle function
Frequency of investigation:( ⭐⭐⭐⭐⭐)
//Fourth Edition function throttle(func, wait, options) { var timeout, context, args, result; var previous = 0; if (!options) options = {}; var later = function() { previous = options.leading === false ? 0 : new Date().getTime(); timeout = null; func.apply(context, args); if (!timeout) context = args = null; }; var throttled = function() { var now = new Date().getTime(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } }; return throttled; } Copy code
⛲ Object article
Can you write a complete deep copy
Frequency of investigation:( ⭐⭐⭐⭐⭐)
const getType = obj => Object.prototype.toString.call(obj); const isObject = (target) => (typeof target === 'object' || typeof target === 'function') && target !== null; const canTraverse = { '[object Map]': true, '[object Set]': true, '[object Array]': true, '[object Object]': true, '[object Arguments]': true, }; const mapTag = '[object Map]'; const setTag = '[object Set]'; const boolTag = '[object Boolean]'; const numberTag = '[object Number]'; const stringTag = '[object String]'; const symbolTag = '[object Symbol]'; const dateTag = '[object Date]'; const errorTag = '[object Error]'; const regexpTag = '[object RegExp]'; const funcTag = '[object Function]'; const handleRegExp = (target) => { const { source, flags } = target; return new target.constructor(source, flags); } const handleFunc = (func) => { //The arrow function returns itself directly if(!func.prototype) return func; const bodyReg = /(?<={)(.|\n)+(?=})/m; const paramReg = /(?<=\().+(?=\)\s+{)/; const funcString = func.toString(); //Match the , function parameter , and , function body respectively const param = paramReg.exec(funcString); const body = bodyReg.exec(funcString); if(!body) return null; if (param) { const paramArr = param[0].split(','); return new Function(...paramArr, body[0]); } else { return new Function(body[0]); } } const handleNotTraverse = (target, tag) => { const Ctor = target.constructor; switch(tag) { case boolTag: return new Object(Boolean.prototype.valueOf.call(target)); case numberTag: return new Object(Number.prototype.valueOf.call(target)); case stringTag: return new Object(String.prototype.valueOf.call(target)); case symbolTag: return new Object(Symbol.prototype.valueOf.call(target)); case errorTag: case dateTag: return new Ctor(target); case regexpTag: return handleRegExp(target); case funcTag: return handleFunc(target); default: return new Ctor(target); } } const deepClone = (target, map = new WeakMap()) => { if(!isObject(target)) return target; let type = getType(target); let cloneTarget; if(!canTraverse[type]) { //Handle objects that cannot be traversed return handleNotTraverse(target, type); }else { //This wave operation is very critical to ensure that the prototype of the object is not lost! let ctor = target.constructor; cloneTarget = new ctor(); } if(map.get(target)) return target; map.set(target, true); if(type === mapTag) { //Process Map target.forEach((item, key) => { cloneTarget.set(deepClone(key, map), deepClone(item, map)); }) } if(type === setTag) { //Process Set target.forEach(item => { cloneTarget.add(deepClone(item, map)); }) } //Working with arrays and objects for (let prop in target) { if (target.hasOwnProperty(prop)) { cloneTarget[prop] = deepClone(target[prop], map); } } return cloneTarget; } Copy code
Reference blog [5]
Implement new
Frequency of investigation:( ⭐⭐⭐⭐)
function createObject(Con) { //Create new object obj // var obj = {}; it's fine too var obj = Object.create(null); //Set obj__ proto__ - > constructor prototype //(not recommended) obj__ proto__ = Con.prototype Object.setPrototypeOf(obj, Con.prototype); //Execute the constructor and accept the return value of the constructor const ret = Con.apply(obj, [].slice.call(arguments, 1)); //If the return value of the constructor is an object, the object is returned directly //Otherwise, obj is returned return typeof(ret) === 'object' ? ret: obj; } Copy code
inherit
Frequency of investigation:( ⭐⭐⭐⭐)
Prototype chain inheritance
Borrow constructor (classic inheritance)
Combinatorial inheritance
Prototype inheritance
Parasitic inheritance
Parasitic combinatorial inheritance
Class implementation inheritance (Supplement)
class Animal { constructor(name) { this.name = name } getName() { return this.name } } class Dog extends Animal { constructor(name, age) { super(name) this.age = age } } Copy code
Reference code [6]
Implement object create
function newCreate(proto, propertiesObject) { if (typeof proto !== 'object' && typeof proto !== 'function') { throw TypeError('Object prototype may only be an Object: ' + proto) } function F() { } F.prototype = proto const o = new F() if (propertiesObject !== undefined) { Object.keys(propertiesObject).forEach(prop => { let desc = propertiesObject[prop] if (typeof desc !== 'object' || desc === null) { throw TypeError('Object prorotype may only be an Object: ' + desc) } else { Object.defineProperty(o, prop, desc) } }) } return o } Copy code
🚂 Function
call
Frequency of investigation:( ⭐⭐⭐⭐)
Function.prototype.myCall = function (thisArg) { thisArg = thisArg || window; thisArg.func = this; const args = [] for (let i = 1; i<arguments.length; i++) { args.push('arguments['+ i + ']') } const result = eval('thisArg.func(' + args +')') delete thisArg.func; return result; } Copy code
bind
Frequency of investigation:( ⭐⭐⭐⭐)
Function.prototype.sx_bind = function (obj, ...args) { obj = obj || window const fn = Symbol() obj[fn] = this const _this = this const res = function (...innerArgs) { console.log(this, _this) if (this instanceof _this) { this[fn] = _this this[fn](...[...args, ...innerArgs]) delete this[fn] } else { obj[fn](...[...args, ...innerArgs]) delete obj[fn] } } res.prototype = Object.create(this.prototype) return res } Copy code
apply
Frequency of investigation:( ⭐⭐⭐⭐)
Function.prototype.myApply = function (thisArg, arr) { thisArg = thisArg || window; thisArg.func = this; const args = [] for (let i = 0; i<arr.length; i++) { args.push('arr['+ i + ']') } const result = eval('thisArg.func(' + args +')') delete thisArg.func; return result; } Copy code
Realize coritization
Frequency of investigation:( ⭐⭐⭐)
Reference code [7]
Implement chain call
Reference code [8]
Partial function
Reference code [9]
🌍 ajax and jsonp
Frequency of investigation:( ⭐⭐⭐)
Implementing ajax
function ajax({ url= null, method = 'GET', dataType = 'JSON', async = true}){ return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest() xhr.open(method, url, async) xhr.responseType = dataType xhr.onreadystatechange = () => { if(!/^[23]\d{2}$/.test(xhr.status)) return; if(xhr.readyState === 4) { let result = xhr.responseText resolve(result) } } xhr.onerror = (err) => { reject(err) } xhr.send() }) } Copy code
Implement jsonp
const jsonp = ({ url, params, callbackName }) => { const generateUrl = () => { let dataSrc = '' for (let key in params) { if (params.hasOwnProperty(key)) { dataSrc += `${key}=${params[key]}&` } } dataSrc += `callback=${callbackName}` return `${url}?${dataSrc}` } return new Promise((resolve, reject) => { const scriptEle = document.createElement('script') scriptEle.src = generateUrl() document.body.appendChild(scriptEle) window[callbackName] = data => { resolve(data) document.removeChild(scriptEle) } }) } Copy code
🛫 ES6
Implement set
class Set { constructor() { this.items = {}; this.size = 0; } has(element) { return element in this.items; } add(element) { if(! this.has(element)) { this.items[element] = element; this.size++; } return this; } delete(element) { if (this.has(element)) { delete this.items[element]; this.size--; } return this; } clear() { this.items = {} this.size = 0; } values() { let values = []; for(let key in this.items) { if(this.items.hasOwnProperty(key)) { values.push(key); } } return values; } } Copy code
Implement map
function defaultToString(key) { if(key === null) { return 'NULL'; } else if (key === undefined) { return 'UNDEFINED' } else if (Object.prototype.toString.call(key) === '[object Object]' || Object.prototype.toString.call(key) === '[object Array]') { return JSON.stringify(key); } return key.toString(); } class Map { constructor() { this.items = {}; this.size = 0; } set(key, value) { if(!this.has(key)) { this.items[defaultToString(key)] = value; this.size++; } return this; } get(key) { return this.items[defaultToString(key)]; } has(key) { return this.items[defaultToString(key)] !== undefined; } delete(key) { if (this.has(key)) { delete this.items[key]; this.size--; } return this; } clear() { this.items = {} this.size = 0; } keys() { let keys = []; for(let key in this.items) { if(this.has(key)) { keys.push(key) } } return keys; } values() { let values = []; for(let key in this.items) { if(this.has(key)) { values.push(this.items[key]); } } return values; } } Copy code
class implementing es6
Reference code [10]
🦉 other
instanceof
Frequency of investigation:( ⭐⭐⭐⭐)
function instance_of(Case, Constructor) { //The basic data type returns false //Compatible with function objects if ((typeof(Case) != 'object' && typeof(Case) != 'function') || Case == 'null') return false; let CaseProto = Object.getPrototypeOf(Case); while (true) { //If the top of the prototype chain is found but not found, false is returned if (CaseProto == null) return false; //Find the same prototype if (CaseProto === Constructor.prototype) return true; CaseProto = Object.getPrototypeOf(CaseProto); } } Copy code
Implement the thousands separator
Frequency of investigation:( ⭐⭐⭐)
var str = "100000000000", reg = /(?=(\B\d{3})+$)/g; str.replace(reg, ",") Copy code
Convert the key of a JSON object from Pascal to Camel
Frequency of investigation:( ⭐⭐⭐)
Reference code [11]
Implement data type judgment function
function myTypeof(obj) { return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase() } Copy code
Implement array to tree
Reference code [12]
Implement sleep function
// promise const sleep = time => { return new Promise(resolve => setTimeout(resolve,time)) } sleep(1000).then(()=>{ console.log(1) }) // ES5 function sleep(callback,time) { if(typeof callback === 'function') setTimeout(callback,time) } function output(){ console.log(1); } sleep(output,1000); Copy code
Implement publish subscribe mode
class EventEmitter { constructor() { this.cache = {} } on(name, fn) { if (this.cache[name]) { this.cache[name].push(fn) } else { this.cache[name] = [fn] } } off(name, fn) { let tasks = this.cache[name] if (tasks) { const index = tasks.findIndex(f => f === fn || f.callback === fn) if (index >= 0) { tasks.splice(index, 1) } } } emit(name, once = false, ...args) { if (this.cache[name]) { //Create a copy. If the same event continues to be registered in the callback function, it will cause an endless loop let tasks = this.cache[name].slice() for (let fn of tasks) { fn(...args) } if (once) { delete this.cache[name] } } } } Copy code
💥 Post language
Friends, if you feel this article is helpful to you, give Peng Shuai a praise 👍 Or focus ➕ Are my greatest support.
In addition, if there is a problem with this article or you don't understand part of the article, you can reply to me in the comment area. Let's discuss together, learn together and make progress together!