1. Write a push?
Array.prototype.push = function(... Items) {// Let O = Object(this); Let len = this.length >>> 0; Let argCount = items. Length >>> 0; Throw New TypeError("The number of array is over The Max value restricted! "); if(len + argCount > 2 ** 51-1) " ) for(let i = 0; i < argCount; i++) { O[len++] = items[i]; } return len; }Copy the code
2. Write a Pop?
Array.prototype.pop = function() { let O = Object(this); let len = this.length >>> 0; if(len == 0) return undefined; else { let element = O[len-1]; delete O[len-1]; this.length = len-1; return element; }}Copy the code
3. Write a map by hand?
Array.prototype.map = function(func,thisArg) { if (this === null || this === undefined) { throw new TypeError("Cannot read property 'map' of null or undefined"); } let O = Object(this); let len = this.length >>> 0; / / judgment callback if (Object. The prototype. ToString. Call (func)! == '[object Function]') throw new TypeError("Cannot read property 'map' of null or undefined"); let A = new Array(len); let k = 0; While (k < len) {if(k in O) {let kValue = O[k]; A[k] = func.call(thisArg,kValue,k,O); } k++; } return A; }Copy the code
4. Write a Reduce?
Array.prototype.reduce = function(func,initialValue) { if(this === undefined || this === null) { throw new TypeError('... '); } if(Object.prototype.toString.call(func) ! == '[object Function]') { throw new TypeError('... '); } let O = Object(this); let len = this.length >>> 0; if(len === 0 && initialValue === undefined) throw new TypeError('... '); let k = 0; let accumulator = initialValue; let kPresent = false; while(! kPresent && k < len) { if(k in O) { kPresent = true; accumulator = O[k]; } k++; } if(! kPresent) throw new TypeError('... '); while(k < len) { if(k in O) { let kValue = O[k]; accumulator = func.call(undefined,accumulator,kValue,k,O); } k++; } return accumulator; }Copy the code
5. Write a filter?
Array.prototype.filter = function(func,thisArg) { if(this === null || this === undefined) { throw new TypeError('... '); } if(Object.prototype.toString.call(func) ! == '[object Function]') { throw new TypeError('... '); } let O = Object(this); let len = this.length >>> 0; let newArrLen = 0; let newArr = []; for(let k = 0; k < len; k++) {{ if(func.call(thisArg,O[k],k,O)) newArr[newArrLen++] = O[k]; } } return newArr; }Copy the code
6. Write a splice?
Array.prototype.splice = function(start,deleteCount,... items) { let O = Object(this); let len = this.length >>> 0; if(len - deleteCount + items.length > 2 ** 53 - 1) { throw new TypeError('... '); } let retArr = []; Start if(start < 0) {start = start+len >= 0? start+len : 0; } else { start = start >= len ? len : start; } if(arguments.length == 1) deleteCount = len-start; else if(deleteCount < 0) deleteCount = 0; else if(deleteCount+start > len) deleteCount = len-start; // If (object.issealed (O) &&items. Length) {// If (object.issealed (O) &&items ! == deleteCount) throw new TypeError('... '); else if(Object.isFrozen(O) && (items.length > 0 || deleteCount > 0)) throw new TypeError('... '); If (deleteCount <= items. Length) {for(let I = start; i < start+deleteCount; i++) { retArr.push(O[i]); O[i] = items[i-start]; If (deleteCount < items.length) {let add = items.length-deleteCount; this.length += add; for(let i = len-1; i >=start+deleteCount; i--) { O[i+add] = O[i]; } for(let i = 0; i < add; i++) { O[start+deleteCount+i] = items[i+deleteCount]; Else if(deleteCount > items. Length) {for(let I = 0; i < deleteCount; i++) { retArr.push(O[i+start]); } for(let i = 0; i < items.length; i++) { O[i+start] = items[i]; } for(let i = 0; i < len - start - deleteCount; i++) { O[start+items.length+i] = O[i+start+deleteCount]; } this.length -= deleteCount-items.length; } return retArr; }Copy the code
This will not put the source code, too much, the interview written so also do not let, that is really exaggerated. This problem mainly investigates the judgment of boundary value. And how well you know the API in general. I think it’s all right. I think it’s on medium.
7, hand tear sort?
Array.prototype.sort = function(callback) { let O = Object(this); let len = this.length >>> 0; _sort(O,len,callback) function _sort(arr,length,compareFn) { / / a for whether to exchange number, b says the number of selected, according to the return to determine whether to need to exchange This is quite hard to understand the if (Object. The prototype. ToString. Call (compareFn)! == '[object Function]') { compareFn = function(a,b) { a = a.toString(); b = b.toString(); if(a === b) return 0; else return a < b ? 1:1; Function insertSort(arr,start = 0,end,compareFn) {for(let I = start; i <= end; i++) { let j; let val = arr[i]; for(j = i; j > start && compareFn(arr[j-1],val) > 0; j--) arr[j] = arr[j-1]; arr[j] = val; Function getMidIndex(arr,begin,end) {let increment = 200 + length & 15; let tmpArr = []; for(let i = begin; i < end; i += increment) { tmpArr.push([i,arr[i]]); } tmpArr.sort((a,b) => { return compareFn(a[1],b[1]); }) return tmpArr[tmpArr.length >> 1][0]; } function quickSort(arr,begin,end) { let midIndex = 0; if(end-begin <= 10) { insertSort(arr,begin,end,compareFn); return; } else if(end-begin <= 1000) midIndex = begin+ (end-begin) >> 1; Else midIndex = getMidIndex(arr,start,end); // Sort the two boundary values with the obtained mid so that the middle number is leftmost. Let TMP = [ARr [midIndex], ARr [begin], ARr [end]]; tmp.sort(compareFn); [arr[begin],arr[midIndex],arr[end]] = [tmp[1],tmp[0],tmp[2]]; // Let I = begin; let t = begin+1; let j = end; let pivot = arr[begin]; While (t <= j) {let order = compareFn(pivot,arr[t]); if(order > 0) [arr[t++],arr[i++]] = [arr[i],arr[t]]; else if(order == 0) t++; else { if(compareFn(pivot,arr[j]) < 0) j--; else if(compareFn(arr[j],pivot) == 0) [arr[t++],arr[j--]] = [arr[j],arr[t]]; else [arr[j--],arr[t++],arr[i++]] = [arr[t],arr[i],arr[j]]; } } quickSort(arr,begin,i-1); quickSort(arr,j+1,end); } quickSort(arr,0,length-1); }}Copy the code
Here draw lessons from some articles, but some articles are some problems, some problems are also very difficult to see,😭, and then their own thinking, basic interview let write sort is more excessive, probably have a train of thought is stronger than the average person. I think compareFn is a little harder to understand.
8. Write a New?
function newFn(Target,... The items) {/ / judging function if (Object. The prototype. ToString. Call (Target). == '[object Function]') throw new TypeError('target is not Function'); Let res = Target(... items); Let obj = object.create (Target. Prototype); Target.call(obj,... items); return (typeof res === 'object' && res ! == null) ? res : obj; }Copy the code
9. Write a bind?
Function.prototype.bind = function(target,... items) { if(Object.prototype.toString.call(this) ! == '[object Function]') throw new TypeError('... ') let self = this; // let resFn = function(... Arg) {// If this is a constructor,this inherits the prototype of resFn, so self is on the prototype of this.self. apply(this instanceof self? this : target,[...items,...arg]); } resFn.prototype = Object.create(self.prototype); return resFn; }Copy the code
10, Hand write apply and call?
Function.prototype.call = Function (target,... The items (direct use of the items is to apply)) {let context = target | | window; // We use Symbol here to ensure uniqueness. Let fn = Symbol('fn'); context[fn] = this; let res = context[fn](... items); delete context[fn]; return res; }Copy the code
11. Deep copy by hand?
function getItemType(item) { prototypeList = { "[object Object]": 'object', "[object Array]": 'array', "[object Map]": 'map', "[object Set]": 'set' }; return prototypeList[Object.prototype.toString.call(item)]; } function funcRes(target) { if(! target.prototype) return target; const bodyTag = /(? <={)(.|\n)+(? =})/m; const paramsTag = /(? < = \ () + (? =\)\s+)/; const targetStr = target.toString(); const params = paramsTag.exec(targetStr); const body = bodyTag.exec(targetStr); console.log(body); if(! body) return null; if(params) return new Function(... params[0],body[0]); else return new Function(body[0]); } function cannotTranverseRes(target) { prototypeList = { '[object Error]': 'error', '[object Function]': 'function', '[object Date]': 'date', '[object RegExp]': 'regExp', '[object Boolean]': 'boolean', '[object Number]': 'number', '[object String]': 'string', '[object Symbol]': 'symbol', } let ctor = target.constructor; let val = prototypeList[Object.prototype.toString.call(target)]; Switch (val) {/ / access using primitive types through the original value of the Object to create a case 'Boolean' : the return of new Object (Boolean) prototype. The valueOf. Call (target)); case 'number': return new Object(Number.prototype.valueOf.call(target)); case 'string': return new Object(String.prototype.valueOf.call(target)); case 'symbol': return new Object(Symbol.prototype.valueOf.call(target)); case('regExp'): return new ctor(target.source,target.flags); case('function'): return funcRes(target); default: return new ctor(target); }} function deepClone(target,map = new map ()) {if((typeof target! == 'object' || target == null) && typeof target ! == 'function') return target; let res; Let type = getItemType(target); if(! type) return cannotTranverseRes(target); else res = new target.constructor(); If (map.has(target)) return target; if(map.has(target)) return target; map.set(target,true); If (type === 'map') {for(let [index,item] of target.entries()) res.set(deepClone(index,map),deepClone(item,map)); } else if(type === 'set') { for(let item of target.values()) res.add(deepClone(item,map)); } else if(type === 'array' || type === 'object') { for(let k in target) { if(target.hasOwnProperty(k)) res[k] = deepClone(target[k],map); } } return res; }Copy the code
Here three big guy wrote the border processing is in place, I looked at the written 😁
12, Hand write a promise(full set of promise, promise -aplus-tests)?
Function Promise(executor) {// Save two states of data this.value = null; this.reason = null; FulfillledArr = []; // Save the function this.fulfillledArr = []; this.rejectedArr = []; this.status = 'pending'; // Ensure that the state can only change once this.flag = false; const _resolve = (val) => { this.value = val; this.status = 'resolved'; this.fulfillledArr.map(cal => {cal()}); } const resolve = (val) => { if(this.status === 'pending' && ! this.flag) { this.flag = true; // If (val! == null && ( typeof val === 'function' || typeof val === 'object' )) { try { let then = val.then; if(typeof then === 'function') { then.call(val,(val) => { this.flag = false; resolve(val) },(rea) => { this.flag = false; reject(rea); }); } else { _resolve(val); } }catch(e) { this.flag = false; reject(e); } } else { _resolve(val); } } } const reject = (reason) => { if(this.status === 'pending' && ! this.flag) { this.flag = true; this.reason = reason; this.status = 'rejected'; this.rejectedArr.map(cal => {cal()}); } } executor(resolve,reject); This is a big pity! // this is a big pity! // this is a big pity! == 'function') fulfilled = value => value; if(typeof rejected ! == 'function') rejected = reason => {throw reason}; Let p2 = new Promise((resolve,reject) => {if(this.status === 'resolved') {// Set process.nexttick (() => {try {let p = fulfilled(this.value) PromiseAndRelation(p,p2,resolve,reject); }catch(e) { reject(e); } }) } else if(this.status === 'rejected') { process.nextTick(() => { try { let p = rejected(this.reason); PromiseAndRelation(p,p2,resolve,reject); }catch(e) { reject(e); } }) } else if(this.status === 'pending') { this.fulfillledArr.push(() => { process.nextTick(() => { try { let p = fulfilled(this.value) PromiseAndRelation(p,p2,resolve,reject); }catch(e) { reject(e); } }) }) this.rejectedArr.push(() => { process.nextTick(() => { try { let p = rejected(this.reason); PromiseAndRelation(p,p2,resolve,reject); }catch(e) { reject(e); } }) }) } }) return p2; Function PromiseAndRelation(p,p2,Toresolve,Toreject) {if(p2 === p) throw new TypeError('cycling reference'); let flag = false; if(p ! = null && ( typeof p === 'function' || typeof p === 'object' )) { try { let then = p.then; if(typeof then === 'function') { then.call(p,(val) => { if(flag) return; flag = true; PromiseAndRelation(val,p,Toresolve,Toreject); },(rea) => { if(flag) return; flag = true; Toreject(rea); }); } else Toresolve(p); }catch(e) { if(flag) return; flag = true; Toreject(e); } } else { // if(flag) return; // flag = true; Toresolve(p); } } Promise.resolve = function(val) { return new Promise((resolve,reject) => { resolve(val); }) } Promise.reject = function(val) { return new Promise((resolve,reject) => { reject(val); }) } Promise.prototype.finally = function(fn) { this.then(() => { fn(); },() => { fn(); }) return this; } Promise.prototype.catch = (rej) => { return this.then(null,rej); // 1, the function must pass in a variable with an iterator. // 2, The function must pass in a variable with an iterator. return new Promise((resolve,reject) => { let res = []; function count(val) { res.push(val); if(res.length === arr.length || arr.size) resolve(res); } if(arr[Symbol.iterator]) { for(let item of arr.values()) { Promise.resolve(item).then((val) => { count(val) },reject); } } else reject(new TypeError(`${typeof arr} ${arr} is not iterable (cannot read property Symbol(Symbol.iterator))`)); }) } Promise.race = function(arr) { return new Promise((resolve,reject) => { if(arr[Symbol.iterator]) { for(let item of arr.values()) { Promise.resolve(item).then((val) => { resolve(val) },reject); } } else reject(new TypeError(`${typeof arr} ${arr} is not iterable (cannot read property Symbol(Symbol.iterator))`)); })} // Create a deferred object promise.defer = promise.deferred = function() {let DFD = {}; dfd.promise = new Promise((resolve,reject) => { dfd.resolve = resolve; dfd.reject = reject; }); return dfd; } module.exports = Promise;Copy the code
13, handwritten anti – shake and throttling?
Function debounse(fn,delay = 1000) {let timer = null; function debounse(fn,delay = 1000) {let timer = null; return (... arg) => { timer && clearTimeout(timer); timer = setTimeout(() => { fn.apply(this,arg); timer = null; }, delay); Function throttle(fn,delay = 1000) {let flag = true; return (... arg) => { if(! flag) return; flag = false; setTimeout(() => { fn.apply(this,arg) flag = true;; }, 1000); }}Copy the code
14, How many ways to implement array deduplication?
Let a = new set (); for(let item of arr.values()) a.add(item); a = [...a]; Let obj = {}; for(let item of arr.values()) obj[item] = item; let res = []; for(let item of Object.values(obj)) res.push(item); Arr.sort (); reduce+sort (); arr.sort(); Let res = arr. Reduce ((pre, item, index) = > {/ / Object is and NaN is + - 1 index = = = 0 | |! Object.is(item,pre[pre.length-1])) && pre.push(item); return pre; },[]) 4, normal comparison // extra space complexity is O[1]. For (let I = 0; i < arr.length; i++) { let t; for(t = i+1; t < arr.length; t++) { if(Object.is(arr[i],arr[t])) break; } t ! = arr.length && arr.splice(t,1); }Copy the code
Observer vs. Publisher/subscriber?
Observers: class Subscribe {constructor() {this.observers = []; } on(callback) { if(typeof callback === 'function') { this.observers.push(callback); } } notify(val) { this.observers.map(cbk => {cbk(val)}); }} Publisher subscriber pattern? Class Subscribe {constructor() {this.eventChannel = {}} // Subscribe and say if on(type, CBK, once = false) {if(! this.eventChannel[type]) this.eventChannel[type] = [{cbk,once}]; else this.eventChannel[type].push({cbk,once}); } // emit emit(type,val) {let events = this.eventChannel[type]; For (let I = 0; for(let I = 0; i < events.length; i++) { events[i].cbk(val); Events [I].once && events.splice(I --,1)}} // Remove CBK callback off(type, CBK) {let events = this.eventChannel[type]; if(events.length === 0) delete this.eventChannel[type]; else { let index = events.findIndex(item => item.cbk === cbk); events.splice(index,1); RemoveAll (type) {this.eventChannel[type] && delete this.eventChannel[type]; }}Copy the code
16. Write a JSONP?
Function jsonp(url,data) {// construct query let params = new URLSearchParams(); for(let [index,item] of Object.entries(data)) { params.set(index,item); } // create a function params.set(' CBK ','_cbk') on the server side for the response; url += '? ' + params.toString(); let script = document.createElement('script'); script.setAttribute('src', url); document.body.appendChild(script); return new Promise((resolve,reject) => { window['_cbk'] = (val) => { resolve(val); document.body.removeChild(script); delete window['_cbk'] } }) } jsonp('http://localhost:8082',{name: 1,val: 2}).then((val) => { console.log(val); }) server: let express = require('express'); let server = express(); Server. Use ('/', (the req, res) = > {res. End (` ${the req. Query. CBK} (data)) `); }) server.listen(8082);Copy the code
17, Write an await?
Function f1() {return new promise ((resolve,reject) => {return new promise ((resolve,reject) => { setTimeout(() => { resolve(1); }, 1000); }) } function* f(a) { let data = yield f1(); console.log(data,a); throw new Error(123); let data1 = yield f1(); console.log(data1,a); return 1 } async function f0(a) { let da = await f1(); console.log(da,a); throw new Error(123); let da1 = await f1(); console.log(da1,a); ** // // genarator function asyncGanerator(func) {return function(... Arg) {let gen = func.apply(this,arg); return new Promise((resolve,reject) => { let genarator; Function next(type,data) {// Reject (reject) {// reject (reject) { genarator = gen[type](data); }catch(e) { return reject(e); } // end return; if(genarator.done === true) { resolve(genarator.value); return; } // iteration. Promise.resolve(genarator.value).then((data) => { next('next',data); },(err) => { next('throw',data); }); } next('next'); }) } } let val = asyncGanerator(f); let val1 = f0(123); val = val(123); setTimeout(() => { console.log(val); console.log(val1); }, 3000);Copy the code
18, Hand write an Instanceof?
Function myInstanceof(val,target) {return if(typeof val! == 'object' || val === null) return false; while(Object.getPrototypeOf(val)) { if(Object.getPrototypeOf(val) === target.prototype) return true; val = Object.getPrototypeOf(val); } return false; }Copy the code
19, Write an object.is?
Function myObjectIs(val1,val2) {// Process +0 and -0. // Handle NaN return val1 === val2? 1/val1 === 1/val2 : (isNaN(val1) && isNaN(val2)); }Copy the code
Writing a function by hand?
Function Curry () {let args = [...arguments]; let _curry =function () { args.push(... arguments); return _curry; } _curry.toString = function() { return args.reduce((pre,val) => pre+val); } return _curry; } the console. The log (curry (1, 2, 3, 4) = = curry (1) (2) (3) (4)) true;Copy the code