前端面试题

2022-03-02  本文已影响0人  波波波bo

前端面经

      任何一个类(函数)都有一个原型对象,原型对象至少有两个属性对象(constructor,prototype),其中constructor
      指向函数本身,proptotype指向父原型对象,函数的实例可以直接访问原型对象,因为实例上__proto__指向构
      造函数的原型对象

手写 call,apply,bind
call 和 apply 的实现思路主要是,首先判断是否是函数调用,如果不是直接抛异常,通过新对象 context 来调用函数,
给 context 创建一个 fn 设置为需要调用的函数,结束调用完成后删除 fn。
bind 实现: 判断是否函数调用,不是直接抛出异常,返回函数:判断函数的调用方式,是否被 new 出来的,如果是 new 出来的直接返回空对象,但是实例的__proto__指向_thisprototype,最后完成函数柯里化 `Array.prototype.slice.call()

call:

Function.prototype.mycall = function(context){
  if(typeof this !== 'function'){
     throw new TypeError('not a function')
  }
  context = context || window
  context.fn = this
  //保存参数
  let args = Array.from(arguments).slice(1)
  //调用函数
  let result = context.fn(...args)
  delete context.fn
  return result
}

apply 实现

  Function.prototype.maApply = function(context){
    if(typeof this !== 'function'){
      throw new TypeError('not a function')
    }
    let result
    context = context || window
    //保存this
    context.fn = this
    if(arguments[1]){
      result = context.fn(...arguments[1])
    }else{
      result = context.fn()
    }
    delete context.fn
    return result
  }

bind 实现

  Function.prototype.myBind = function(context){
    if(typeof this !== 'function'){
      throw new TypeError('not a function')
    }
    //保存调用bind的函数
    const _this = this
    //保存参数
    const args = Array.prototype.slice.call(arguments,1)
    //返回一个整数
    return function F(){
      if(this instanceof F){
        //是new出来的 返回一个空对象,且使创建出来的实例的__proto__指向_this的prototype, 且完成函数柯里化
        return new _this(...args,...arguments)
      }else{
        //如果不是new出来的改变this的指向,完成柯里化
        return _this.apply(context,args.concat(...arguments))
      }
    }
  }

new 的实现

  function myNew(fn,...args){
    //创建一个空对象
    let obj = {}
    //使空对象的隐式原型指向原函数的显示原型
    obj.__proto__ = fn.prototype
    //this指向obj
    let result = fn.apply(obj,args)
    return result instanceof Object ? result : obj
  }

深拷贝

function isObject(o){
  return Object.prototype.toString.call(o) === "[object Object]" || Object.prototype.toString.call(o) === "[object Array]"
}
function deepClone(o,hash=new map()){
  if(!isObject(o)) return o
  if(hash.has(o)) return hash.get(o)
  let obj = Array.isArray(o)?[]:{}
  hash.set(o,obj)
  for(let i in o){
    if(isObject(o[i])){
      obj[i] = deepClone(o[i],hash)
    }else{
      obj[i] = o[i]
    }
  }
  return obj
}
上一篇下一篇

猜你喜欢

热点阅读