简单实现 call bind方法

93 阅读1分钟

function Symbol (obj) {

//  保证传入对象中 新建的这个方法是唯一 key

  let x = (Math.random() + new Date().getTime()).toString(32).slice(0, 8) 
  // 利用时间戳 保证 X 值为 obj 中的唯一 key 值
  if (obj.hasOwnProperty(x)) {
    //  hasOwnProperty 对象自带方法, 判断传入值在已有对象中是否已存在
      return mySymbol(obj) //递归调用
  } else {
      return x
  }

}

Function.prototype.MyBind = function (context) {

// Function.prototype.MyCall = function (context) {

  // context就是demo中的Person1
  // 必须此时调用MyCall的函数是say方法,
  // 那么我们只需要在context上扩展一个say方法指向调用MyCall的say方法这样this
  context = context || window
  let fn = Symbol(context) // 保证 fn 为 context 中为一值
  context[fn] = this //Mycall里边的this就是我们虚拟的say方法
  let arg = [...arguments].slice(1)
  // context[fn](...arg) // MyCall // call 可以传入很多参数
  context[fn](arg) // MyBind // bind 传入的第二各参数为为数组
  delete context[fn] // 最后删除 新增到传入对象中的方法

}

let Person = {

  name: 'Tom',
  say() {
      console.log(this)
      console.log(`我叫${this.name}`)
  }

}

Person1 = { name: 'Tom11' }

// Person.say.call(Person1) // 原 call 方法

// 测试 // Person.say.MyCall(Person1,1,5,8) //我叫Tom1

Person.say.MyBind(Person1, [1, 5, 8]) //我叫Tom1