JS中,call和apply同为回调函数,功能完全相同,只是传递的参数不一样。下面进行简单的解析:
一、call
call有两个主要:给函数传递参数;扩充函数的作用域。扩充函数作用域很重要,即改变函数的上下文(改变this的指向)。下面简单介绍一下,代码如下:
window.job = 'teacher';
showJob = () => {
console.log(this.job);
}
showJob(); //teacher
上述代码中,this指向window,即this=window对象。当然,如果在代码中加入严格模式:
'use strict';
此时会报错,因为在严格模式下,es6语法需要babel进行转译。看如下一段代码:
'use strict';
window.job = 'teacher';
function showJob() {
console.log(this.job);
}
showJob();
此时,代码会报错:“job undefined”,原因严格模式下,此时的this指向undefined。现在忽略这种情况,回到问题,如果不想this指向window,要怎么改变函数中的this,看下列代码:
window.job = 'teacher';
const studentObj = {'job': 'student'};
function showJob() {
console.log(this.job);
}
showJob.call(studentObj); //student
在showJob调用的时候,函数后面多加一个call,然后在参数中放入this指向的对象即可。call在调用时使用,也叫动态绑定。call的重要功能,通俗讲就是改变this的指向。
二、apply
apply的功能和call完全一样,只是传递参数不一样,这也是他们的唯一区别,下面简单介绍一下:
代码段1:
function sum(num1, num2){
return num1 + num2;
}
function callSum(num1, num2){
return sum.call(null, num1, num2);
}
callSum(10, 20); //30
代码段2:
function sum(num1, num2){
return num1 + num2;
}
function callSum(num1, num2){
return sum.apply(null, [num1, num2]);
}
callSum(10, 20); //30
上述两个代码段的功能一样。
注意:此时this作为调用对象不能忽略,如果要使用默认对象则可以使用null作为第一个参数。
总结:
1、call和apply的功能相同,只是传递的参数的方式不一样,而我们在传递参数的时候经常是传入arguments对象,如下:
return sum.apply(null, arguments)
arguments它本身就是一个类数组,所以这种情形apply应用广点。
2、call的主要作用是扩展函数的作用域,即改变this指向。