前端JS面试手写函数

1.用一个柯里化函数实现累加

// 柯里化函数
function currying(fn,length) {
    var length = length || fn.length;
    return function(...arg) {
        if(arg.length >= length) {
            return fn(...arg);
        } else {
            return currying(fn.bind(null,...arg),length-arg.length);
        }
    }
}
function $add(a1,a2,a3,a4) {
    return a1 + a2 + a3 + a4;
}
var add = currying($add,4);
console.log(add(1,2,3,4));
console.log(add(1,2)(3,4));
console.log(add(1)(2)(3,4));
console.log(add(1)(2)(3)(4));

2.实现一个bind函数

//myBind函数
Function.prototype.myBind = function (argThis,...arg) {
    const _Fn = this;
    return function() {
        const args = [...arg,...arguments];
        return _Fn.apply(argThis,args);
    }
}

var name = 'Nick'
function sayName() {
    return this.name
}
var obj = {
    name: 'Lily'
}
console.log(sayName())
var sayNamenew = sayName.myBind(obj);
console.log(sayNamenew())

3.实现一个new函数

//myNew函数
function Dog(name) {
    this.name = name;
    this.bar = function() {
        console.log(`my name is ${this.name}`)
    }
    // return this
}

function myNew(fn,...arg) {
    // let _Fn = new Object();
    // _Fn.__proto__ = fn.prototype;
    let _Fn = Object.create(fn.prototype);
    let result = fn.apply(_Fn,arg);
    return typeof result === 'object' ? result : _Fn;
}

var teddy = myNew(Dog,'Teddy');
console.log(teddy.name)
teddy.bar();

4.手写一个观察者模式

function Observer(){
        this.fns=[];
    }
    Observer.prototype={
        //订阅
        subscribe:function(fn){
            this.fns.push(fn);
        },
        //退订
        unsubscribe:function(fn){
            this.fns=this.fns.filter(
                function(el){
                    if(el!==fn){
                        return true;
                    }
                }
            )
        },
        //发布
        update:function(o,thisObj){
            var scope=thisObj || window;
            this.fns.forEach(
                function(el){
                    el.call(scope,o);
                });
        }
    }
    var o=new Observer;
    var f1=function(data){
        console.log('Robbin: ' + data + ', 赶紧干活了!');
    };
    var f2 = function (data) {
        console.log('Randall: ' + data + ', 找他加点工资去!');
    };
    var f3 = function (data) {
        console.log('Li: ' + data + ', 我要揍他!');
    };
    //f1,f2,f3订阅了
    o.subscribe(f1);
    o.subscribe(f2);
    o.subscribe(f3);
    //f1取消了订阅
    o.unsubscribe(f1);
    //发布
    o.update('Tom回来了');

    //输出结果
    //Randall: Tom回来了, 找他加点工资去!
    //Li: Tom回来了, 我要揍他!

5.手写一个防抖回流函数
防抖:

function debounce(fn, wait) {    
        var timeout = null;    
        return function() {        
            if(timeout !== null)   clearTimeout(timeout);        
            timeout = setTimeout(fn, wait);    
        }
}
// 处理函数
function handle() {    
      console.log(Math.random()); 
}
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));

节流:

//节流throttle代码(时间戳):
var throttle = function(func, delay) {            
  var prev = Date.now();            
  return function() {                
    var context = this;                
    var args = arguments;                
    var now = Date.now();                
    if (now - prev >= delay) {                    
      func.apply(context, args);                    
      prev = Date.now();                
    }            
  }        
}        
function handle() {            
  console.log(Math.random());        
}        
window.addEventListener('scroll', throttle(handle, 1000));
// 节流throttle代码(定时器):
var throttle = function(func, delay) {            
    var timer = null;            
    return function() {                
        var context = this;               
        var args = arguments;                
        if (!timer) {                    
            timer = setTimeout(function() {                        
                func.apply(context, args);                        
                timer = null;                    
            }, delay);                
        }            
    }        
}        
function handle() {            
    console.log(Math.random());        
}        
window.addEventListener('scroll', throttle(handle, 1000));

你可能感兴趣的:(前端JS面试手写函数)