javascript中的call、apply和bind

前言

在工作中会经常碰到或者使用到call,apply以及bind,之前只是简单了解这三个原型链上的函数,并没有很深入的搞懂,所以今天看了一些文章总结,觉得写的很好,对自己也有所启发,我自己也总结记录一下。


一、call,apply和bind的基本介绍

三者的使用方法:
fun.call(thisarg, param1, param2,...)
fun.apply(thisarg, [param1, param2, ...])
fun.bind(thisarg, param1, param2, ...)

call,apply和bind的作用都是改变this的指向即改变函数执行时的上下文,三者既有相同之处,也有区别;

1.返回值:

  • call/apply 返回的fun的执行结果;
  • bind返回的是fun的拷贝,并拥有指定的this和初始值参数;

2.参数:

thisarg(可选)

  • fun的this指向thisArg对象
  • 非严格模式下:thisArg指定为null,undefined,fun中的this指向window对象.
  • 严格模式下:fun的this为undefined
  • 值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象,如 String、Number、Boolean

param(可选):传给fun的参数

  • 可为空值或者null,undefined
  • apply的第二个参数格式为数组

3.调用call/apply/bind的fun必须为函数


二、call,apply和bind的用途

三者主要的作用就是改变this的指向;只不过call和apply直接返回的是函数的执行结果,而bind返回的是一个拷贝函数,并指定this和初始参数;需再调用返回的拷贝函数可得执行结果。

1、简单的例子

//call和apply实现对象的继承
function super() {
    this.a = 'hello world',
    this.print = function() {
        console.log(this.a)
    }
}
function sub() {
    super.call(this); //或者super.apply(this)
    this.print()
}
sub(); // 1

//bind绑定回调函数的this指向
class Page {
    constructor(callback) {
        this.className = 'Page'
        // callBack() // 直接执行的话 由于class 内部是严格模式,所以this 实际指向的是 undefined
        this.MessageCallBack = callback // 回调函数的this 隐式绑定到class page
        this.MessageCallBack('发给注册页面的信息') // 执行PageA的回调函数
    }
}

class PageA {
    constructor() {
        this.className = 'PageA'
        this.pageClass = new Page(this.handleMessage.bind(this)) //绑定回调函数的this指向
        // 或者同 this.pageClass = new Page(() => this.handleMessage()) // 箭头函数绑定this指向
    }
    handleMessage(msg) {
        console.log('comunication...', this.className, msg)
    }
}
new PageA()