大家都知道,JavaScript 是一门弱类型动态语言,运行期间才会去做数据类型的检查。一定程度上,这会给我们的项目带来很多不确定性,但是凡事有利有弊,善于利用它的动态性特点也能给我带来相当的便利,写出很多骚操作~

其中把语言本身的动态性演绎得淋漓尽致的非 Function.prototype.apply Function.prototype.call Function.prototype.bind 这三个方法莫属,它们可以在代码的运行过程中动态地改变 this 的指向。

首先,我们可以看到,这三个方法都是 Function 构造函数上的原型方法,也就是说:在 JavaScript 语言中,所有的函数都可以调用这三个方法,不论它是普通函数还是作为方法的函数,亦或是匿名函数。

其次,这三个方法都可以改变 this 的指向,只是在使用方式上稍有不同,需要仔细辨析。

1. Apply

这个三个方法中,以 apply 最为基础,可以通过 apply 去实现 call 以及 bind
我们先看一下 apply 的定义:

1
Function.prototype.apply(thisArg[, argsArray])

从定义可以知道,apply 接受两个参数:thisArgargsArray,我们可以看到参数 argsArray 是可选的,其实参数 thisArg 也是可选的,我们看下面几个例子:

1.1 thisArg 为 null

1
2
3
4
let max = Math.max.apply(null, [1, 2, 3])
console.log(max) // 3
max = Math.max.apply(null, null)
console.log(max) // 3