这仨兄弟有个共同的存在意义:改变函数执行的上下文,或者说他们可以改变当前函数的执行环境,本质上其实就是可以改变函数this的指向。为什么要这么做呢?那是因为我们想在我们当前的函数中使用另一个函数的功能,从而实现函数复用,简化代码,提高代码可维护性。
三个方法的区别
这三个方法发挥的作用其实非常相似,但是还是有一些差别的。 call和apply的区别,他们俩之间的差别是参数的差别,call和apply的第一个参数都是要改变执行上下文的对象,但是call从第二个参数开始以参数列表的形式存在,apply则是把剩余的参数放在数组里作为第二个参数。
let arr = [1, 3, 2, 6];
console.log(Math.max.call(null, 1, 3, 2, 6)); // 6
console.log(Math.max.apply(null, arr1)); //6
call、apply和bind的区别 call和apply改变了函数的上下文后就开始执行,而bind则是返回了改变上下文后的一个函数,它不会立即执行,而是需要我们之后调用这个返回的函数。
call的用法
Function.call(obj, [param1, [param2, ... [,paramN]]]) 注意:
- 调用call的对象必须是Function
- call的第一个参数是对象,调用call的函数的this将指向这个对象,如果不传的话将默认为window。
- 第二个参数开始后,可以接收任意多个参数,每一个参数都会映射到function相应参数位置上。
apply的用法
Function.apply(obj,[argArray]) 注意:
- 它的调用者必须是一个Function
- 第一参数必须是对象,这个和call一样
- 第二个参数必须是数组或者类数组,并且会映射到function相应参数位置
bind的用法
Function.bind(obj,arg1[,arg2[,...]]]) 注意:
- 如果第一个参数是null或者undefined,则this指向全局对象window
- 使用bind返回一个新的函数,需要调用才能得到结果
使用案例和小技巧
- call可以用于是实现继承
function superClass() {
this.a = 1;
this.print = function() {
console.log(this.a);
}
}
function subClass(){
superClass.call(this);
this.print();
}
subClass(); //1
- call可以实现借用方法
- apply可以用来求数组中的最大值
let max = Math.max.apply(null, array)
- apply可以方便地实现数组的合并
let arr1 = [1,2,3];
let arr2 = [4,5,6];
Array.prototype.push.apply(arr1,arr2);
console.log(arr1); //[1,2,3,4,5,6]