美文网首页
call,apply,binde

call,apply,binde

作者: 熊啊熊c | 来源:发表于2021-03-28 17:41 被阅读0次

什么是call,apply,bind

我们都知道,这三个方法都是和this指向有关的,那么具体是什么呢,简单来讲就是将某个函数放在指定的上下文变量中,在函数被调用的时候,this指向所绑定的对象。

语法

  1. func.call(thisArg, param1, param2, ...)
    func函数运行时的上下文绑定到thisArg对象中,并给func传入param1param2参数

  2. func.apply(thisArg, [param1,param2,...])
    func函数运行时的上下文绑定到thisArg对象中,并给func传入[param1,param2]类数组参数

  1. func.bind(thisArg, param1, param2, ...)
    作用同1,但bind返回的是func函数的拷贝,而不是执行结果

什么是类数组
具有某些数组方法的对象变量,如:

let arrayLike = {
    0: 1,
    1: 2,
    2: 3,
    length: 3
};

类数组 arrayLike 可以通过下标进行调用,具有length属性,同时也可以通过 for 循环进行遍历。
但是需要注意的是:类数组无法使用 forEach、splice、push 等数组原型链上的方法,毕竟它不是真正的数组。那么类数组想使用数组原型链上的方法,该怎么办呢?请继续往下看。

call,apply,bind的作用

核心理念:借用方法

使用场景

  1. 方法借用(call,apply)
  2. 处理回调函数this丢失问题(bind)
class Page {
    constructor(callBack) {
        this.className = 'Page';
        this.MessageCallBack = callBack; //回调函数
        this.MessageCallBack('发给注册页面的信息'); // 执行PageA的回调函数
    }
}

class PageA {
    constructor() {
        this.className = 'PageA';
        //问题在下面这句
        this.pageClass = new Page(this.handleMessage);//注册页面 传递回调函数 
    }

    // 与页面通信回调
    handleMessage(msg) {
        console.log('处理通信', this.className, msg); // 'Page' this指向错误
    }
}

let a = new PageA()
a.pageClass.MessageCallBack()//>>处理通信 Page apple

我们想要的结果是在调用a.pageClass.MessageCallBack打印出的className是A类的名称而不是Page类的名称。

  1. 为什么会出现这个问题,就要考虑到执行a.pageClass.MessageCallBack发生了什么,我们知道,函数在哪里运行,this就会在哪里
  2. 由于是a的pageClass属性是Page类的一个实例,所以相当于把handleMessage方法,交给Page实例使用,所以在a.pageClass.MessageCallBack中的this是处在Page实例的环境中,所以就会打印出Page而不是PageA
  • 修改方案
  1. 使用bind方法
this.pageClass = new Page(this.handleMessage.bind(this));

作用:实例Page的时候,告诉构造函数,在使用此参数(函数)的时候,是在PageA的实例下运行的

  1. 使用箭头函数
this.pageClass = new Page(() => this.handleMessage());

作用:因为箭头函数比较特殊,相当于告诉this.handleMessage()方法,你在被调用的时候this就是pageA实例里,不会因传递而影响指向

手写call,apply,bind

未完待续

相关文章

网友评论

      本文标题:call,apply,binde

      本文链接:https://www.haomeiwen.com/subject/qrwphltx.html