随着前端技术的快速迭代,现在大厂的要求也在不断提高。各种算法、原理等成为了与心仪企业的阻隔。结合了自
己的面试经验,做了如下总结。
一、排序相关(是根据出现频率整理的顺序)
-
冒泡排序
function BubbleSort(arr) { if(arr.length > 0){ let len = arr.length; for(let end = len - 1; end > 0; end--){ for(let i = 0; i < end; i++) { if(arr[i] > arr[i + 1]){ [arr[i],arr[i+1]] = [arr[i+1],arr[i]]; } } } return arr; }else{ return []; } } -
快速排序
function quickSort(arr) { if(arr.length > 0){ quick(arr, 0, arr.length - 1); }else{ return []; }} function quick(arr, firstVal, lastVal){ if(firstVal < lastVal){ //随机找一个值,然后和最后一个值进行交换,将经典排序变为快速排序 let i = firstVal + Math.floor(Math.random() * (lastVal - firstVal + 1)), j = lastVal; [arr[i],arr[j]] = [arr[j],arr[i]] let tempArr = partition(arr, firstVal, lastVal, arr[lastVal]); quick(arr, firstVal, tempArr[0]); quick(arr, tempArr[1], lastVal); } } //返回的值是小于区域的最大索引和大于区域的最小索引 function partition(arr, firstVal, lastVal, num){ let less = firstVal - 1; let more = lastVal + 1; let cur = firstVal; while(cur < more){ if(arr[cur] < num){ [arr[less+1],arr[cur]] = [arr[cur],arr[less+1]]; }else if(arr[cur] > num) { [arr[more-1],arr[cur]] = [arr[cur],arr[more-1]]; }else{ cur++; } } return [less, more]; } -
选择排序
function SelectionSort(arr) { if(arr == null || arr.length < 0) { return []; } for(var i = 0; i < arr.length - 1; i++) { var minIndex = i; for(var j = i + 1; j < arr.length; j++) { minIndex = arr[j] < arr[minIndex] ? j : minIndex; } [arr[i],arr[minIndex]] = [arr[minIndex],arr[i]]; } return arr; } -
插入排序
function insertSort(arr) { if(arr == null || arr.length <= 0){ return []; } var len = arr.length; for(var i = 1; i < len; i++) { for(var j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { [arr[j],arr[j+1]] = [arr[j+1],arr[j]]; } } return arr; }
二、手写实现call、apply、bind
-
call: fn.call(context, 1, 2, 3, 4)
Function.prototype.MyCall = function(content){ const self = content || window; const args = Array.from(arguments).slice(1); const self.fn = this; const result = arguments.length > 1 ? self.fn(...args) : self.fn(); delete self.fn; return result; } -
apply: fn.apply(context, [1, 2, 3, 4])
Function.prototype.MyApply = function(content,args = []){ const self = content || window; self.fn = this; const result = args.length > 0?self.fn(args):self.fn(); delete self.fn; return result; } -
bind: fn.bind(context, 1, 2)(3, 4)
Function.prototype.MyBind = function(content){ const self = this; const args = Array.from(arguments).slice(1); return function F(){ if(this instanceof F){ return new self(...args,...arguments); }else{ const doubleArgs = args.concat(arguments); return self.apply(content,doubleArgs); } } }
其中context为this指向,三种形式的结果是一致的。call与apply参数形式不同,bind返回的是一个未执行的方法,执行的时候可以继续传参,实现了函数的柯里化。
三、手写promise
Promise 的三种状态:fulfilled(执行态)、rejected(拒绝态)、pending(等待态)。
-
成功时,不可转为其他状态,且必须有一个不可改变的值(value)
-
失败时,不可转为其他状态,且必须有一个不可改变的原因(reason)
function Promise(excutor) { let self = this; self.status = 'pending'; self.value = null; self.reason = null; self.onFulfilledCallbackArr = []; self.onRejectedCallbackArr = []; function resolve(value) { if (self.status === 'pending') { self.value = value; self.status = 'fulfilled'; self.onFulfilledCallbackArr.forEach(item => item()); } } function reject(reason) { if (self.status === 'pending') { self.reason = reason; self.status = 'rejected'; self.onRejectedCallbackArr.forEach(item => item()); } } try { excutor(resolve, reject); } catch (err) { reject(err); } } Promise.prototype.then = function(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(data) { resolve(data) }; onRejected = typeof onRejected === 'function' ? onRejected : function(err) { throw err }; let self = this; if (self.status === 'fulfilled') { return new Promise((resolve, reject) => { try { let x = onFulfilled(self.value); if (x instanceof Promise) { x.then(resolve, reject); } else { resolve(x); } } catch (err) { reject(err); } }) } if (self.status === 'rejected') { return new Promise((resolve, reject) => { try { let x = onRejected(self.reason); if (x instanceof Promise) { x.then(resolve, reject); } else { resolve(x); } } catch (err) { reject(err); } }) } if (self.status === 'pending') { return new Promise((resolve, reject) => { self.onFulfilledCallbackArr.push(() => { let x = onFulfilled(self.value); if (x instanceof Promise) { x.then(resolve, reject); } else { resolve(x); } }); self.onRejectedCallbackArr.push(() => { let x = onRejected(self.reason); if (x instanceof Promise) { x.then(resolve, reject); } else { resolve(x); } }) }) } }; Promise.prototype.catch = function(fn) { return this.then(null, fn); };