一些面试经常考的js功能函数笔记(不一定对)
1 //防抖 经过一定的延迟执行一次 接受一个函数 返回防抖的函数 2 function debounce(fn,delay){ 3 4 var _args = Array.prototype.slice.call(arguments,2) //获取参入的参数 5 var timer = null; 6 return function(){ 7 var that = this //保存this对象 因为有些事件触发需要保存当前的对象 8 var _secondArgs = [].concat(Array.prototype.slice.call(arguments),_args) //获取参入的参数 9 clearTimeout(timer); 10 timer = setTimeout(function(){ 11 fn.apply(that,_secondArgs) 12 },delay) 13 } 14 } 15 16 var test = document.getElementById('test') 17 var hello = '456' 18 test.name = '123' 19 var hh = throttle(function(){ 20 console.log(this.name,hello) 21 },2000,hello) 22 23 test.onclick = hh 24 25 26 //节流 27 function throttle(fn,delay){ 28 var _args = Array.prototype.slice.call(arguments,2) //获取参入的参数 29 var timer = null; 30 return function(){ 31 var that = this //保存this对象 因为有些事件触发需要保存当前的对象 32 var _secondArgs = [].concat(Array.prototype.slice.call(arguments),_args) //获取参入的参数 33 if(!timer){ 34 timer = setTimeout(function(){ 35 fn.apply(that,_secondArgs); 36 timer = null 37 },delay) 38 } 39 40 } 41 } 42 43 //var a = b.bind() 44 //bind的模拟实现
1 Function.prototype._bind = function(context){ 2 var that = this 3 var _args = Array.prototype.slice.call(arguments,1); 4 5 var _fun=function(){ 6 var args = _args.concat(Array.prototype.slice.call(arguments)); 7 if(this instanceof _fun){ 8 return that.apply(this,args) 9 }else{ 10 return that.apply(context,args) 11 } 12 } 13 14 var _fonp = function(){}; 15 _fonp.prototype = this.prototype 16 _fun.prototype = new _fonp() 17 return _fun 18 19 }
67 68 //数组扁平化 69 function flattern(array){ 70 var _returnArray = [] 71 array.forEach(function(ele){ 72 if(Array.isArray(ele)){ 73 //还是数组的话继续递归 74 _returnArray = _returnArray.concat(flattern(ele)) 75 }else{ 76 _returnArray.push(ele) 77 } 78 }) 79 80 return _returnArray 81 82 } 83 84 console.log(flattern([1,2,[3,4,[5,6,7]],[8,9,[10,[11,12[13,14]]]]]))
1 //深拷贝 2 function deepCopy(object){ 3 var isObject = function(target){ 4 return (typeof(target) ==='object' && object !== null); 5 } 6 7 var _returnObject = Array.isArray(object) ? [] : {} 8 9 10 if(!isObject(object)){ 11 throw new Error('深拷贝对象必须为数组或者对象哦'); 12 } 13 //遍历对象 14 for(var key in object){ 15 if(object.hasOwnProperty(key)){ 16 //如果key值是null的话 直接进行赋值 如果不做这一步的话会在上面直接返回一个false值 17 if(object[key] === null){ 18 _returnObject[key] = object[key] 19 }else if(isObject( object[key] )){ 20 //递归调用自身 21 _returnObject[key] = deepCopy(object[key]) 22 } 23 else{ 24 _returnObject[key] = object[key] 25 } 26 } 27 } 28 return _returnObject 29 } 30 var test = [null,2,[3,undefined,5,[1]],{key:null,value:2},'123',function(){console.log(2)},false] 31 var testObject = deepCopy(test) 32 test[1] = 'test' 33 test[2][0] = 'test' 34 test[2][3].push('test') 35 test[3].key = 'test' 36 test[5] = '1111' 37 console.log(testObject);
1 //函数柯丽化 用闭包把参数保存起来,当参数的数量足够执行函数了,就开始执行函数 2 function curry(fn,setArray){ 3 var length = fn.length //获取需要传参的长度 4 var setArray = setArray || [] //已经设置了的传参 5 6 return function(){ 7 var args = setArray.concat(Array.prototype.slice.call(arguments)); //获取额外传入的参数 8 //如果传参的长度小于真实需要参数的长度 那么就返回 重新返回一个函数 9 if(args.length <length){ 10 return curry.call(this,fn,args) 11 }else{ 12 //大于的话就执行函数 13 return fn.apply(this,args) 14 } 15 } 16 } 17 18 var _testCurry = curry(function(a,b,c,d,f,g){ 19 console.log(a,b,c,d,f,g) 20 }) 21 22 _testCurry(1)(1)(2)(3,4,5,6,7);
1 //实现一个eventEmitter 2 class eventEmitter { 3 constructor(maxLength = 10){ 4 this._events = Object.create(null); 5 this.maxLength = maxLength 6 } 7 8 addListners(type,cb){ 9 //判断是否已经添加了这个方法了 如若添加了的话必须放进去一个数组中 超过的话直接报错 10 if(this._events[type] && this._events[type].length === this.maxLength) throw new Error(`超出${this.maxLength}个监听事件限制啦`); 11 this._events[type] = this._events[type] ? [...this._events[type],cb] : [cb] 12 13 } 14 emitEvents(type,...args){ 15 if(this._events[type]){ 16 this._events[type].forEach((listner) =>{ 17 listner.apply(this,args) 18 }) 19 } 20 } 21 //监听一次 只触发一次就要删除 22 once(type,cb){ 23 //先绑定 在addListners的基础上调用之后就删除 重新声明一个函数 24 function onceListners(...args){ 25 cb && cb.apply(this,args); 26 //调用完成之后删除这个监听器 27 this.removeListner(type,onceListners) 28 29 } 30 this.addListners(type,onceListners) 31 } 32 removeListner(type,cb){ 33 const removeTarget = this._events[type] 34 if(removeTarget){ 35 //如果没传cb 说明全部删除 36 if(!cb){ 37 this._events[type] = [] 38 } 39 this._events[type] = this._events[type].reduce((prev,cur) => { 40 if(cur !==cb){ 41 prev.push(cur) 42 } 43 44 return prev 45 },[]); 46 47 } 48 } 49 //设置最大监听数 50 setMaxListners(n = 10){ 51 this.maxmaxLength = n 52 } 53 static getInstance(maxLength = 10){ 54 if(eventEmitter._instance){ 55 return eventEmitter._instance 56 }else{ 57 eventEmitter._instance = new eventEmitter(maxLength); 58 return eventEmitter._instance 59 } 60 } 61 } 62 const _fn = function(data){ 63 console.log('once'+data) 64 } 65 const _test = eventEmitter.getInstance(3); 66 _test.addListners('hhh',function(data){ 67 console.log('hhh111'+data,this._events) 68 }) 69 _test.once('hhh1',_fn) 70 _test.addListners('hhh',(data)=>{ 71 console.log('hhh222'+data) 72 }) 73 _test.emitEvents('hhh',123); 74 75 _test.emitEvents('hhh1',123);
lazyMan
1 //lazyman 2 3 class LazyMan{ 4 constructor(name){ 5 this.name = name; 6 this.task = []; 7 8 let consoleName = () =>{ 9 console.log(`i am lazyName ${this.name}`) 10 this.next() 11 } 12 this.task.push(consoleName); 13 setTimeout(() =>{ 14 console.log('start'); 15 this.next(); 16 },0) 17 18 } 19 sleep(time){ 20 21 let _sleep = () =>{ 22 23 setTimeout(() =>{ 24 console.log(`${this.name} sleep ${time} alearady`); 25 this.next() 26 },time*1000); 27 } 28 29 this.task.push(_sleep); 30 return this 31 } 32 eat(data){ 33 let _eat = () =>{ 34 console.log(`${this.name}eat${data}`); 35 this.next() 36 } 37 this.task.push(_eat); 38 return this 39 } 40 next(){ 41 //每次执行完一个任务获取下一个任务 并且去除一开始的任务 42 let nextTask = this.task.shift(); 43 44 //console.log(nextTask) 45 nextTask && nextTask() 46 } 47 } 48 49 let man = new LazyMan('wuhr') 50 man.sleep(0.5).eat('fan').sleep(4).eat('zhopu');