alert 输入的是字符串

一、手写call&bind

~function anonymous(proto){  function bind(context = window, ...args){    return (...amArgs) => {      this.apply(context, args.conact(amArgs));    }  }  function call (context, ...args){    context === null ? context = window : null;    let type = typeof context;    if(type !== 'object' && type !== 'function' && type !== 'symbol' ){      switch(type){        case "number":          context = new Number(context);          break;        case 'string':          context = new String(context);          break;        case 'boolean':          context = new Boolean(context);          break;      }    }    context.$fn = this;    let result = context.$fn(...args)     delete context.$fn;    return result;  } proto.call = call  proto.bind = bind}(Function.prototype)

二、节流防抖

节流: 多少秒再执行,如果没到执行工夫内持续点击,则从新计算执行工夫 利用: input输入

function debounce(fn, delay){    let timer = null;    return function (){      if(timer){        clearTimeout(timer)      }      timer = setTimeout(() => {        fn.call(this, ...arguments)        timer = null;      }, delay)    }  }  // 示例:  handleChange = (e) => {    this.value = e.target.value;  }  Input.onChange = debounce(handleChange, 500);  Input.onChange  = function(){     if(timer){       clearTimeout(timer);     }     timer = setTimeout(() => {       handleChange.call(this, ...arguments)     }, 500)  }

防抖: 设置两秒距离点击一次,无论你点击多少次,都是两秒之后执行 利用: resize,scroll
1、工夫戳

function throttle(fn, interval){  // 此时立刻执行  let last = new Date().getTime();  return function(){    let now = new Date().getTime();    if(now - last > interval){      last = now;      fn.apply(this, [...arguments])    }   }}

2、定时器

function throttle(fn, interval){  let timer = null  return function(){    if(!timer ){    timer = setTimeout(() => {        fn.apply(this, [arguments])        clearTimeout(timer)      }, interval)    }  }}

3、工夫戳和定时器联合形式

 function throttle(fn, delay){ // 节流 10    let timer = null;    let startTime = new Date().getTime();  30    return function (){      let curTime = new Date().getTime();      let remaining = delay - (curTime - startTime);      let context = this;      let args = arguments;      clearTimeout(timer);      if(remaining <= 0){        fn.apply(context, args);        startTime = curTime;      } else {        timer = setTimeout(fn, remaining);      }    }  }

三、实现一个new

function self_new(Func, ...args){  // 默认创立一个实例对象(而且是属于以后这个类的一个实例)  let obj = {};  obj.__proto__ == Func.prototype; // IE 大部分浏览中不容许咱们间接操作__proto__;  //  let obj = Object.create(Dog.prototype); 等价于下面两行  let result = Func.call(obj, ...args);  if((typeof result === 'object' && result !== null) || ( typeof result === 'function') ){    return result  }  return obj;  // 也会把类当做一般函数执行  // 执行的时候要保障this指向创立的实例}

四、继承的四种形式

1、原型继承

  function A () {    this.x = 100;  }  A.prototype.getX = function getX () {    console.log(this.x)  }  function B (){    this.y = 200;  }  // 原型继承  B.prototype = new A()  B.prototype.getY = function getY(){    console.log(this.y);  }  let b = new B;  // 特点: 并不会把父类的办法克隆给子类,而是建设了子类和父类的原型链查找机制  // 重定向子类的原型后,默认会失落原有的constructor属性,  // 任何一个子类能够批改父类上的属性办法,  // 父类的公有属性办法变成子类的私有属性

2、call继承

  function A (){    this.x = 100;  }  A.prototype.getX = function getX(){    console.log(this.x)  }  // 把父类当做一般函数执行,让其执行的时候,办法中的this变为子类的实例即可  function B(){    A.call(B);    this.y = 200;  }  B.prototype.getY = function getY(){    console.log(this.y)  }  let b = new B;  // 只能继承父类的公有属性,继承的公有属性赋值给子类实例的公有属性  // 父类的原型办法无奈被继承

3、寄生组合继承(perfect)

// call继承实现公有属性继承  // 原型继承实现私有属性继承  function A (){    this.x = 100;  }  A.prototype.getX = function getX(){    console.log(this.x)  }  // 把父类当做一般函数执行,让其执行的时候,办法中的this变为子类的实例即可  function B(){    A.call(B);    this.y = 200;  }  // Object.create :创立一个空对象,让其__proto__ 指向A.prototype  B.prototype  = Object.create(A.prototype);  B.prototype.constructor =   B.prototype.getY = function getY(){    console.log(this.y)  }  let b = new B;

4、class继承

class A {    constructor(){      this.x = 100;    }    // 设置A.prototype上的办法    num = 1000;    // 把A当做一般对象设置的属性和办法    static n = 2000;    static getH () {      console.log('123123')    }    getX(){      console.log(this.x)    }  }  class B extends A{    constructor(){      super();      this.y = 300;    }    getY(){      console.log(this.y);    }  }

五、深拷贝

JOSN.parse(JSON.stringify(obj))缺点: 本义之后,正则 => {}  函数 => null
function deepClone(obj){  if(obj  === null) return null;  // 如果是根本数据值或者函数,也能够间接返回即可(函数无须要克隆)  if(typeof obj !== 'object') return obj;  // 如果是正则  if(Object.toString.call(obj) === '[Object RegExp]') return new RegExp(obj);  // 如果是日期格局  if(Object.toString.call(obj) === '[Object Date]') return new Date(obj);    // obj.constructor:找到所属类原型上的constructor,而原型上的constructor指向的事以后类的自身 ==> 保障传递进来什么类型的值,咱们最初创立的newObj也是对应类型  let newObj = new obj.constructor;  for(let key in obj){    if(!obj.hasOwnProperty(key)) break;    newObj[key] = deepClone(obj[key])   }   return newObj;}

六、实现promise

class MyPromise{  constructor(executor){    // 每一个promise实例都有一个状态和后果属性    this.PromiseStatus = 'pending';    this.PromiseValue = undefined;    this.resoveFnArr = [];    this.rejectFnArr = []    // 定义resolve/reject办法用来扭转promise实例的状态和后果    let change = (status, value) => {      if(this.PromiseStatus !== 'pending') return;      this.PromiseValue = value;      this.PromiseStatus = status;      let fnArr = status === 'resolved'? this.resoveFnArr: this.rejectFnArr;      fnArr.forEach(item => {        if(typeof item !== 'function'){          return         }        item(this.PromiseValue);      })    }    let resolve = result => {      if(this.resoveFnArr.length){        change('resolved', result)        return       }      let delayTimer = setTimeout(() => {        change('resolved', result)        clearTimeout(delayTimer)      }, 0)    }    let reject = resason => {      if(this.resoveFnArr.length){        change('rejected', resason)        return      }      let delayTimer = setTimeout(() => {        change('resolved', result)        clearTimeout(delayTimer)      }, 0)    }    // 每一次new Promise 都会执行executor函数     try{      executor(resolve, reject);    } catch(err){      reject(err);    }  }  then(resolveFn, rejectFn){    // 每一次执行then都会返回一个新的promise实例    // this.resoveFnArr.push(resolveFn);    // this.rejectFnArr.push(rejectFn);    // 如果传递的参数不是函数(null/或者不传递),咱们让胜利或者失败传递顺延    if(typeof resoveFn !== 'function'){      resolveFn = (result) => {        return result;      }    }    if(typeof rejectFn !== 'function'){      rejectFn = (reason) => {        return MyPromise.reject(reason);      }    }    return new MyPromise((resolve, reject) => {      // 执行resolve/reject决定新的实例是胜利还是失败的       // 只有执行新实例的executor函数中的resolve/reject就晓得新的实例是胜利的还是失败的      this.resoveFnArr.push((result) => {       try{         //不报错,则承受办法的返回后果,会依据后果判断胜利还是失败        let x = resolveFn(result);        console.log('设置then执行的数据', x , x instanceof MyPromise)        if(x instanceof MyPromise){          x.then(resolve, reject);          return        }        resolve(x);      } catch(err){        // 执行报错代表新实例是失败的        reject(err)      }      });      this.rejectFnArr.push((reason) => {        try{           // 不报错,则承受办法的返回后果,会依据后果判断胜利还是失败          let x = rejectFn(reason);          if(x instanceof MyPromise){            x.then(resolve, reject);            return           }          resolve(x);        }catch(err){          // 执行报错代表新实例是失败的          reject(err)        }      });    })  }  // MyPromise.prototype.catch(fn) === MyPromise.prototye.then(null, fn)  catch(rejectFn){    return this.then(null, rejectFn);  }  // 静态方法  static resolve(result){    return new MyPromise((resolve, reject) => {      resolve(result);    })  }  static reject(reason){    return new MyPromise((resolve, reject)=> {      reject(reason);    })  }  static all(arr){    return new MyPromise((resolve,reject) => {       let index = 0;      let results = [];      for(let i = 0; i < arr.length; i++){        let item = arr[i];        if(!(item instanceof MyPromise)) continue;        item.then( result => {          index++;          results[i] = result;          if(index === arr.length){            resolve(results);          }        }).catch(reason => {          reject(reason)        })      }    })  }}