一些面试经常考的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');

 

posted @ 2018-05-22 12:07  carrot萝卜  阅读(403)  评论(0编辑  收藏  举报