JS高级<模拟一个call方法>

85 阅读1分钟
   思路:
   1.首先函数都是Function函数的实例化(详情请看前面的原型三角链),
   所以我们只要在Function的原型(Function.prototype)添加一个方法,模拟call,
   那么所有函数都可以调用到。
   2.取一个不同于call的名字方法(取名mycall)
   3.正常情况下,如果想让一个方法中的this指向某个对象,最简单的方式是:某个对象.方法()
   4.谁调用方法,谁就是方法里面的this,现在是say在调用mycall方法,所以mycall方法中的this就是say
   
//在Function.prototype添加mycall方法
Function.prototype.mycall = function(newobj) {
        /*此时是say调用了mycall方法,所以this指向say,即this == say
        newobj通过传参进入到mycall方法里面,然后我们往newobj对象添加一个say方法*/    
        newobj.fn = this
        //此时因为调用模式是方法调用模式,是newobj调用了方法,所以此时this指向newobj
        newobj.fn()
        /*最后,我们只是希望newobj调用say方法,但是不希望添加say方法,
        所以最后我们进行删除处理*/
        delete newobj.fn
}

let obj = {
        name: 'jack',
        say: function() {
          console.log(`我的名字是:${this.name}`)
    }
}

let newobj = {
        name: 'rose'
}

      obj.say()  //输出 我的名字是jack
      obj.say.mycall(newobj) //输出 我的名字是rose
总结:call是方法的方法(在上面的代码中,say是方法(函数),say调用了mycall,
所以mycall是say方法的方法。call实质上就是改变了this的指向。

obj.say()中,this指向obj
obj.say.mycall(newobj)中,this指向newobj