自己十指敲call、apply、bind

基础的不能再基础的前端面试题 手写call、apply、bind
当然 不要那么繁琐,迅速且简洁明了的写出来应该是会很加分的吧?
记录一波。。。

call

function person(a, b, c) {
  console.log(this.name)
  console.log(a, b, c)
}

let demo = { name: '大神仙' }

Function.prototype.myCall = function (context, ...arg) {

  context = context || window

  if (typeof this != 'function') {
    throw new Error('Type error')
  }

  //防止 context中的fn重复 使用Symbol保证唯一性
  const fn = Symbol('fn')
  
  context[fn] = this

  const res = context[fn](...arg)

  delete context[fn]

  return res

}

person.myCall(demo, '开心', '快乐', '笑')
image.png

apply

function person(a, b, c) {
  console.log(this.name, a, b, c)
}

let demo = { name: '大神仙' }

Function.prototype.myApply = function (context = window, arg) {

  if (typeof this != 'function') {
    throw new Error('Type error')
  }

  //防止 context中的fn重复 使用Symbol保证唯一性
  const fn = Symbol('fn')
  
  context[fn] = this

  let res

  //判断第二个参数是否是数组
  if (Object.prototype.toString.call(arg) !== '[object Array]') {
    res = context[fn](...[...arguments].slice.call([...arguments], 1))
  } else {
    res = context[fn](...arg)
  }


  delete context[fn]

  return res

}

person.myApply(demo, ['开心', '快乐', '笑'])
person.myApply(demo, '开心', '快乐', '笑')
image.png

bind

function person(a, b, c, d) {
  console.log(this.name, a, b, c, d)
}

let demo = { name: '大神仙' }

Function.prototype.myBind = function (context, ...args) {
  if (typeof this !== 'function') {
    throw new Error("Type Error");
  }
  let _this = this
  //bind返回函数
  return function Fn() {
    // bind还可以使用new
    if (this instanceof Fn) {
      return new _this(...args, ...arguments)
    }

    return _this.apply(context, [...args, ...arguments])
  }

}


person.myBind(demo, '开心', '快乐', '笑')('哈哈哈哈')

let newPerson = person.myBind(demo, '不开心', '伤心', '哭唧唧')
let p = new newPerson('呜呜呜呜')
nice.gif
happy.gif

你可能感兴趣的:(自己十指敲call、apply、bind)