数组扁平化

var arr = [1, [2, 3, [4, [2, [3]]]]]
var flat = function (array) {
    let arr = []
    array.forEach(item => {
        if (Array.isArray(item)) {
            arr = arr.concat(flat(item))
        } else {
            arr.push(item)
        }
    })
    return arr
}
console.log(flat(arr))

防抖

var debounce = function (fn, delay = 300) {
    let timer = null
    return function (...args) {
        clearTimeout(timer)
        timer = setTimeout(() => {
            fn.call(this, ...args)
        }, delay);
    }
}

节流

var throttle = function (fn, delay = 300) {
    let flag = false
    return function (...args) {
        if (flag) return 
        flag = true
        setTimeout(() => {
            fn.call(this, ...args)
            flag = false
        }, delay);
    }
}

instanceOf

var myInstanceOf = function (L,R) {
    var O = R.prototype
    var L = L.__proto__
    while (1) {
        if(L===null) return false
        if(L === R) return true
        L = L.__proto__
    }
}

jsonp

function jsonp(url, jsonpCallback, success) {
    let script = document.createElement('script')
    script.src = url
    script.async = true
    script.type = 'text/javascript'
    window[jsonpCallback] = function (data) {
        success && success(data)
    }
    document.appendChild(script)
}
jsonp('http://xxxx','callback',function (value) {
    console.log(value)
})

函数柯里化

function curry(fn, args) {
    var _this = this
    var len = fn.length
    var args = args || []
    return function () {
        var _args = Array.prototype.slice.call(arguments)
        Array.prototype.push.apply(args, _args)
        if (_args.length < len) {
            return curry.call(_this, fn, _args)
        }
        return fn.apply(this, _args)
    }
}
/**
 * 实现一个add函数
 * add(1)(2)(3) = 6;
 * add(1, 2, 3)(4) = 10;
 * add(1)(2)(3)(4)(5) = 15;
 */
function add() {
    // 第一次执行时,定义一个数组专门用来存储所有的参数
    var _args = [...arguments];
    // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
    var _adder = function () {
        _args.push(...arguments);
        return _adder;
    };
    // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    _adder.toString = function () {
        return _args.reduce(function (a, b) {
            return a + b;
        });
    }
    return _adder;
}
console.log(add(1, 2)(2, 2)(2));

美团二面

实现一个函数,这个函数有两个参数,一个参数是fn 一个是count 要求,参数fn是一个promise函数, 如果执行成功直接返回,如果失败就重试count次数,到达count之后就返回失败

function func(fn, count) {
    count--
    fn().then(res => {
        console.log('执行成功');
        return
    }).catch(err => {
        if (count === 0) {
            console.log('执行失败')
            return
        }
        func(fn, count)
    })
}
let p = function () {
    return new Promise((resolve, reject) => {
        let num = Math.random(0, 1)
        console.log(num)
        if (num > 0.7) {
            resolve()
        } else {
            reject()
        }
    })
}
func(p, 5)

单例模式

//1
function A(name){
    // 如果已存在对应的实例
   if(typeof A.instance === 'object'){
       return A.instance
   }
   //否则正常创建实例
   this.name = name

   // 缓存
   A.instance =this
   return this
}
var a1 = new A() 
var a2= new A()
console.log(a1 === a2)//true
//2
function A(name){
  var instance = this
  this.name = name
  //重写构造函数
  A = function (){
      return instance
  }
}
var a1 = new A() 
var a2= new A()
console.log(a1 === a2)//true