手写call

<script>
    /**
     * call方法
     * 第一个参数为null或者undefined时,this指向全局对象window,
     * 值为原始值的指向该原始值的自动包装对象,如 String、Number、Boolean
    */
    Function .prototype.myCall = function(context,...args) {
      if(context === undefined || context === null) {
        context = window  
      }

      if(typeof context !== 'undefined' && typeof context !== 'function' && typeof context !== 'object') {
        context = new Object(context)
      }

      const fn = Symbol() //声明一个Symbol类型的属性,表示是一个唯一的属性,防止被其他同名属性覆盖
      context[fn] = this // this指向调用call方法的那个对象
      const result = context[fn](...args) // 执行
      delete context[fn] // 删除fn属性
      return result
    }


    function cc() {
      console.log(this.name)
    }
    obj = {
      name:'xx'
    }
    cc.myCall(obj)

    /**
     * cc.myCall(obj) -> 首先this指向,改为obj
     * 所以myCall函数中context[fn] = this,在上面的函数中,this指向的是function cc()
     * 然后context[fn]() ->可以当成 context.fn()
     * 需要理解的是 context[fn]() 等同于 cc.myCall(obj),而myCall函数第一个参数就是函数内部的this
     * cc.myCall(obj) 就相当于  
     * obj.cc = cc  声明一个cc属性,将cc函数赋值给这个属性
     * obj.cc() 调用
    */




  </script>

 

posted @ 2020-04-19 16:28  yuliy  阅读(121)  评论(0)    收藏  举报