手写call 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Function .prototype .myCall = function (context,...args ){ if (typeof this !== 'function' ){ throw new typeError ('not a function' ) } context = context||window context.fn = this let res = context.fn (...args) delete context.fn return res } let obj1 = { getName (...args ){ console .log (this .name +args[0 ]+args[1 ]) } } let shili = { name :'shaking' } obj1.getName .myCall (shili,1 ,2 ,3 ,4 )
手写apply 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 Function .prototype .myApply = function (context,args ){ if (typeof this !== 'function' ) { throw new TypeError ('not a function' ) } context = context||window context.fn = this res = context.fn (args) delete context.fn return res } var sobj = { getName :function (a ){ return this .name +a } } var person = { name :"shaking" } console .log (sobj.getName .myApply (person,[1 ,2 ,3 ]))
手写bind 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Function .prototype .myBind = function (context, ...args ) { let _me = this ; let fn = function ( ) { } let toBeBind = function ( ) { let _this = this instanceof toBeBind ? this : context; return _me.apply (_this, [...args, ...arguments ]); } fn.prototype = _me.prototype ; toBeBind.prototype = new fn (); return toBeBind; } let fn = new fn1.myBind (obj)
手写new 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Function .prototype .myNew = function (constructor,...args ){ var o = {}; o.__proto__ = constructor.prototype let result = constructor.apply (o,args); return result&&typeof (result == 'object' )?result :o; }
实现Object.creact 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Object .prototype .myCreate = function (proto, propertyObj = undefined ) { if (proto === null ) { throw 'TypeError' ; } else { function fn ( ) { }; fn.prototype = proto; const obj = new fn (); if (propertyObj !== undefined ) { Object .defineProperties (obj, propertyObj); } if (proto === null ) { obj.__proto__ = null ; } return obj; } }
手写instanceof 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function myInstanceof (left, right ) { let L = left while (true ) { if (L.__proto__ == null ) { return false } if (L.__proto__ == right.prototype ) { return true } L = L.__proto__ } } let a = [1 , 2 , 3 , 4 ]let b = { a : 1 } let res = myInstanceof (a, Object )console .log (res)
手写深拷贝 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function deepClone (value,map= new WeakMap () ) { if (value == null ) return value; if (typeof value !== 'object' ) return value; if (value instanceof RegExp ) return new RegExp (value); if (value instanceof Date ) return new Date (value); let cloneObj = Array .isArray (value)?[]:{}; if (map.get (value)) { return map.get (value); } map.set (value,cloneObj); for (let key in value){ if (value.hasOwnProperty (key)) { cloneObj[key] = deepClone (value[key],map); } } return cloneObj; }
防抖函数 1 2 3 4 5 6 7 8 9 function debounce (fn, wait ) { let timer = null ; return function ( ) { clearTimeout (timer); timer = setTimeout (()=> { fn.apply (this , arguments ) }, wait); } }
节流函数 1 2 3 4 5 6 7 8 9 10 11 12 13 function throttle (fn, wait ) { let timer = null return function ( ) { if (timer) { return } else { timer = setTimeout (() => { fn.apply (this , arguments ) timer = null }, wait) } } }
实现函数柯里化/实现add(1)(2)(3) 函数柯里化指的是将能够接收多个参数的函数转化为接收单一参数的函数,并且返回接收余下参数和结果的新函数的技术。
好处是让函数参数的处理更加自由,可以用作工具函数。
举例来说,一个接收3个参数的普通函数,在进行柯里化后, 柯里化版本的函数接收一个参数并返回接收下一个参数的函数, 该函数返回一个接收第三个参数的函数。 最后一个函数在接收第三个参数后, 将之前接收到的三个参数应用于原普通函数中,并返回最终结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function add (...args) { return args.reduce ((a, b ) => a + b) } function currying (fn) { let args = [] return function temp (...newArgs) { if (newArgs.length ) { args = [ ...args, ...newArgs ] return temp } else { let val = fn.apply (this , args) args = [] return val } } } let addCurry = currying (add)console .log (addCurry (1 )(2 )(3 )(4 , 5 )()) console .log (addCurry (1 )(2 )(3 , 4 , 5 )()) console .log (addCurry (1 )(2 , 3 , 4 , 5 )())
手写promise 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 const PENDING = "pending" ;const FULFILLED = "fulfilled" ;const REJECTED = "rejected" class myPromise { constructor (executor ) { try { executor (this .resolve , this , this .reject ); } catch { this .reject (err); } } state = PENDING ; fulfilledCallbacks = []; rejectedCallbacks = []; value = null ; reason = null ; resolve = (value ) => { if (this .state === PENDING ) { this .state = FULFILLED ; this .value = value; while (this .fulfilledCallbacks .length ) this .fulfilledCallbacks .shift ()(value); } } reject = (reason ) => { if (this .state === PENDING ) { this .state = REJECTED ; this .reason = reason; while (this .rejectedCallbacks .length ) this .rejectedCallbacks .shift ()(value); } } then (onFulfilled, onRejected ) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value; onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }; const promise2 = new myPromise ((resolve, reject ) => { const resolveMicrotask = ( ) => { queueMicrotask (() => { try { const x = onFulfilled (this .value ); this .resolvePromise (x, promise2, resolve, reject); } catch (err) { reject (err); } }) } const rejectMicrotask = ( ) => { queueMicrotask (() => { try { const x = onRejected (this .reason ); this .resolvePromise (x, promise2, resolve, reject); } catch (err) { reject (err); } }) } if (this .state === FULFILLED ) resolveMicrotask (); else if (this .state === REJECTED ) rejectMicrotask (); else if (this .state === PENDING ) { this .fulfilledCallbacks .push (onFulfilled); this .rejectedCallbacks .push (onRejected); } }) return promise2; } resolvePromise (x, self, resolve, reject ) { if (x === self) { throw new Error ("" ) } if (x instanceof myPromise) { x.then (resolve, reject); } else { resolve (x); } } }
promise.all 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function all (arr ) { let resArr = []; let count = 0 ; return new Promise ((resolve, reject ) => { arr.forEach ((el, index ) => { if (el instanceof Promise ) { Promise .resolve (el).then (res => { resArr[index] = res; count++; }, err => reject (err)) } else { resArr[index] = el; count++; } if (count === arr.length ) { resolve (resArr); } }); }) }
promise.allSettled 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function allSettled (arr ) { let resArr = []; let count = 0 ; arr.forEach ((el, index ) => { if (el instanceof Promise ) { Promise .resolve (el).then (res => { resArr[index] = res; count++; }, err => { resArr[index] = err; count++; }) } else { resArr[index] = el; count++; } if (count === arr.length ) { resolve (resArr); } }) }
promise.any 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 any (arr ) { let count = 0 ; return new Promise ((resolve,reject )=> { arr.forEach ((el ) => { if (el instanceof Promise ) { Promise .resolve (el).then (res => { resolve (res); },err => { count++; if (count === arr.length ) { reject (new Error ("All promises were rejected" )); } }) }else { resolve (el); } }) }) }
promise.race 1 2 3 4 5 6 7 8 9 10 11 12 13 function race (arr ) { return new Promise ((resolve, reject ) => { arr.forEach (el => { if (el instanceof Promise ) { Promise .resolve (el).then (res => resolve (res), err => reject (err)) } else { resolve (el); } }) }) }
promise.finally 1 2 3 4 5 6 7 8 9 Promise .prototype .finally = function (callback ) { return this .then (res => { callback (); return res; },err => { callback (); throw err; }) }
实现数组扁平化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 const res = [];const fn = arr => { for (let i = 0 ;i<arr.length ;i++) { if (Array .isArray (arr[i])) { fn (arr[i]); }else { res.push (arr[i]); } } } let arr = [1 , [2 , [3 , [4 , 5 ]]], 6 ,[1 ,2 ,[3 ,4 ]]];fn (arr);const res1 = arr.flat (Infinity )const myFlat = arr => { return arr.toString ().split ("," ).map (i =>Number (i)) } let res2 = myFlat (arr);console .log (res2);const myFlat2 = arr => { return arr.reduce ((pre,cur ) => { pre.concat (Array .isArray (cur)?flat (cur):cur) },[]) } const myFlat3 = arr => { while (arr.some (item =>Array .isArray (item))) { arr = [].concat (...arr); } return arr; }
数组去重 1 2 3 4 5 6 7 8 9 10 11 12 const unique = (arr ) => { return [...new Set (arr)]; } const unique2 = (arr ) => { return arr.filter ((val,index ) => { return arr.indexOf (val) === index; }) } [1 ,2 ,[1 ,3 ,[4 ,5 ],[1 ,2 ]],6 ,7 ,8 ,[6 ,8 ]]
数组转树状结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function convert (list ) { const res = []; const idMapping = data.reduce ((acc,el,i )=> { acc[el.id ] = i; return acc },{}) let root; data.forEach (el => { if (el.parentId ===null ) { root = el; } const parentEl = data[idMapping[el.parentId ]]; parentEl.children = [...(parentEl.children ||[]),el] }); }
树状结构转数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 let res = [];function treeToArray (obj ) { res.push (obj); if (obj.children .length ) { for (const item of obj.children ) { treeToArray (item); } } return res; } function treeToArray2 (obj ) { const stack = []; const res = []; stack.push (obj); while (stack.length ) { const item = stack[0 ]; res.push (item); stack.pop (); if (item.children &&item.children .length ) { stack.push (...item.children ) } } return res; }
排序 冒泡排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 const bubble = (nums ) =>{ for (let i=0 ;i<nums.length ;i++){ for (let j=0 ;j<nums.length -1 -i;j++){ if (arr[j]>arr[j+1 ]){ let temp = arr[j+1 ]; arr[j+1 ] = arr[j]; arr[j] = temp; } } } return nums; }
快速排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const quickSort = array => { if (array.length <=1 ){ return array } let left = [] let right = [] let pIndex = Math .floor (array.length /2 ) let p = array.splice (pIndex,1 )[0 ] for (let i=0 ;i<array.length ;i++){ if (array[i]<p){ left.push (array[i]) } else { right.push (array[i]) } } return quickSort (left).concat ([p], quickSort (right)) }
归并排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 const mergeSort = (arr ) => { var len = arr.length ; if (len<2 ) { return arr; } let middle = Math .floor (len/2 ); let left = arr.slice (0 ,middle); let right = arr.slice (middle); return merge (mergeSort (left),mergeSort (right)); } const merge = (left,right ) => { let res = []; console .time ("11" ); while (left.length &&right.length ) { if (left[0 ]<=right[0 ]) { res.push (left.shift ()); } else { res.push (right.shift ()); } } while (left.length ) { res.push (left.shift ()); } while (right.length ) { res.push (right.shift ()); } console .timeEnd ("22" ); return res; } const arr = [5 ,4 ,6 ,3 ,6 ,8 ,9 ,2 ];let res = mergeSort (arr);console .log (res);