实现手写call

76 阅读1分钟

大家都知道call,apply,bind,都是改变this 指向,具体怎么实现的,先来看看代码

     let person={
            getName:function(){
                 return this.name
            }
        }

        let man={
            name:"张三"
        }
        
       //  先执行一下getName函数,但是它里边没有name这个属性,所以打印出来是undefied
        console.log(person.getName())
     //如果想把man里边的name给getName的话,这时我们可以用call改变this指向
        
        console.log(person.getName.mycall(man))

那call具体是在哪里呢,此时我们去打印一下它的原型对象。

 console.log(person.getName.prototype)
 
 //打印台的显示
 1.  {constructor: ƒ}
1.  1.  constructor: ƒ ()
    1.  1.  arguments: null
        1.  caller: null
        1.  length: 0
        1.  name: "getName"
        1.  prototype: {constructor: ƒ}
        1.  [[FunctionLocation]]: 1.html:17
        1.  [[Prototype]]: ƒ ()
        1.  1.  apply: ƒ apply()
            1.  arguments: (...)
            1.  bind: ƒ bind()
            1.  call: ƒ call()
            1.  caller: (...)
            1.  constructor: ƒ Function()
            1.  length: 0
            1.  name: ""
            1.  toString: ƒ toString()
            1.  Symbol(Symbol.hasInstance): ƒ [Symbol.hasInstance]()
            1.  get arguments: ƒ ()
            1.  set arguments: ƒ ()
            1.  get caller: ƒ ()
            1.  set caller: ƒ ()
            1.  [[FunctionLocation]]:
            1.  [[Prototype]]: Object
            1.  [[Scopes]]: Scopes[0]
        1.  [[Scopes]]: Scopes[2]
    1.  [[Prototype]]: Object

打印出来可以看到call是挂载到原型对象上边的,所以要实现这个功能,我们也要在原型上边挂载一个方法。 现在来手写一个call,先在原型上挂载一个MyCall的方法。 此时的this指向的是person.getName,因为是person.getName调用的,并且这边有两个条件,this必须是个函数,而且必须要传值,不传的话默认是window。

     Function.prototype.mycall=function(man){
            // 第一步先去调用getName函数,并将this指向getName函数
            const res=this()
           
            return res
        }
        console.log(person.getName.mycall(man))
         

此时getName函数的this指向的是this,那怎么让this指向man呢?

         Function.prototype.mycall=function(man){
        // 假设man上边有个函数,用this把它替换掉,此时指向的就是man了
                man.fn=this
                const res=man.fn()

                return res
            }
         
          console.log(person.getName.mycall(man))

手写call基础完成,关于涉及的this指向的知识点没有详细讲解,有需要改进的点欢迎多多留言