this ‘’家族成员‘’:call apply bind

80 阅读3分钟

u=2775038568,1348507314&fm=253&fmt=auto&app=138&f=JPEG.webp

this

在讲这些this家族成员之前,我们有必要先了解一下this指针,如果还有小伙伴不清楚的,可以去看看这篇文章浅谈this,里面有我们平常遇到的this使用情况。

大同小异

bind、call、apply可以说大同小异,首先,他们都是用来指定一个函数内部的this的值,只是在用法上面略微有些差异。

首先call() 方法接收的语法和作用与apply()方法相似,区别就在于,call()接收的是一个参数列表,而apply()方法接收的是一个包含多个参数的数组

let obj = {

   a: 1,
   
   get: function() {
   
        return 2
        
 }
 
let o = obj.get

o.call({}, 1, 2)

o.apply({}, [ 1, 2 ])

bind的第二个之后的参数为调用它的函数的参数列表,而bind()函数会返回一个新的方法,并且该方法满足柯里化,仍可以传递参数,但这个方法的this不可被call、apply、bind改变,如果使用new实例化,那么原本通过bind绑定的this指向的对象会失效,this将指向到新实例化的对象上,且可以使用原方法原型链上的属性或方法。

手写思路

记住精髓,函数干的事情就是改变this指针的指向,这些函数被调用的时候必须是this,那么此时手写函数的时候,我们只需要将其挂载在该this上,并且执行掉,之后再将这个属性删除,那么就可以悄然的改变this指向,废话不多说我们上代码!

call

Function.prototype.mycall = function(context){

    //调用call的是this  mycall需要被a调用,mycall的this将会指向a函数

     if(typeof this !== 'function'){

         //如果调用的不是一个函数,报错

          throw new TypeError('Error')

     }

     context = context || window

     //把调用的那个函数获取到,复制到context对象中去

      context.fn = this //获取a函数作为fn属性

     context.fn() //调用fn属性,执行函数a

     delete context.fn //删除fn
     
     }
     
     a.mycall(b)

apply

var b = {

    name:'aa'

}

function a(e,ee) {

        console.log(this.name);

        console.log(e + ee);

}

// a.call(b) //b.a()

//a.call() 不传参数指向window

//函数才能调用,函数原型链

Function.prototype.myapply = function(context){

    //调用call的是this  mycall需要被a调用,mycall的this将会指向a函数

     if(typeof this !== 'function'){

         //如果调用的不是一个函数,报错

          throw new TypeError('Error')

     }

     context = context || window

     //把调用的那个函数获取到,复制到context对象中去

      context.fn = this //获取a函数作为fn属性

     let result = context.fn(...arguments[1]) //调用fn属性 //防止a函数有返回值

     delete context.fn //删除fn

     return result

}
a.myapply(b,[1 ,2])

bind

Function.prototype.mybind = function(context){

    //调用call的是this  mycall需要被a调用,mycall的this将会指向a函数

     if(typeof this !== 'function'){

         //如果调用的不是一个函数,报错

          throw new TypeError('Error')

     }

     let _this = this

     context = context || window

     let args = [...arguments].slice(1) //除了第一个参数之后的

     return function F(){ //即c的函数

        //this代表的函数执行

        _this.apply(context,args.concat(Array.from(arguments))) //concat() 字符串拼接

        //调用a  b.a()

        // _this.apply(context,args.concat(...arguments))

    }  

}

let c = a.mybind(b,1)

总结

总之,掌握原理还是很重要的,我是小白,我们一起学习js 文章如有错误,请在下方指出,谢谢!