js中call,apply和bind方法的区别和使用场景
Function.prototype.call()
functionFun.call(thisArg, arg1, arg2, ...)
用法:
用来在调用函数时,临时替换一次函数内部的this。
参数:
thisArg:调用时用来替换函数内部的this
值。
arg1, arg2, …:指定的参数列表。
返回值:
使用调用者提供的 this
值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined
案例:
//全局有一个计算器方法,lilei要用这个方法去计算出来自己的工资
function calc(base, bonus1, bonus2){
console.log(`${this.ename} 的总工资是: ${base+bonus1+bonus2}`)
};
let lilei={
ename:"lilei",
};
calc.call(lilei,10000,1000,2000);//13000
//错误写法:lilei.calc(10000,1000,2000),因为clac这个方法在全局对象window中存着,并不在lilei的原型链上
//让类数组对象强行调用数组家的slice方法,将类数组对象转化为数组
Array.prototype.slice.call(arguments);
以上案例想要调用方法函数,第一步都是先去找到这个方法函数,然后用call去强行调用它,把新的this指向的对象放进去。
[].slice.call(arguments,开始截取位置)
这是第二个案例的另一个写法,arguments本不是数组,它是类数组对象,所以它不能直接去调用数组家的方法。想要调用数组家的slice方法就必须先去找到他,通过Array实例化的对象找到了这个方法,然后强行用call调用。
Function.prototype.apply()
functionFun.apply(thisArg, arr)
用法:
用来在调用函数时,临时替换一次函数内部的this。
参数:
thisArg:调用时用来替换函数内部的this
值。
arr:指定的数组。
返回值:
使用调用者提供的 this
值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined
案例:
//全局有一个计算器方法,lilei要用这个方法去计算出来自己的工资
function calc(base,bonus1,bonus2){
console.log(`${this.ename} 的总工资是: ${base+bonus1+bonus2}`)
};
let lilei={
ename:"lilei",
}
calc.apply(lilei,[10000,1000,2000]);//13000
apply和call相同点是都能临时替换一次函数中的this。只不过apply比call多一项功能——先打散数组为单个值,再分别传给函数实参。
Function.prototype.bind()
var newfunctionFun = functionFun.bind(thisArg, arg1, arg2, ...)
用法:
创建一个和原函数一模一样的新函数,将新函数中的this永久替换为指定的对象
参数:
thisArg:调用时用来替换函数内部的this
值。
arr:指定固定的参数列表。
返回值:
使用调用者提供的 this
值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined
注意:
只 创建 新函数,而不是调用函数的意思,也不会改变原函数。
案例:
function calc(base,bonus1,bonus2){
console.log(`${this.ename} 的总工资是: ${base+bonus1+bonus2}`)
};
let lilei={ ename:"lilei", }
let lcalc=calc.bind(lilei,10000);
//新函数function lcalc(base,bonus1,bonus2){
//this.ename永久替换为lilei.ename
//形参base永久=10000
//}
//从此调用lcalc,无需反复.call(lilei,10000),其中的this永远指lilei,base永远是10000
lcalc(1000,2000);
lcalc(2000,3000);
注意:
所有回调函数,真正被调用时,前边是没有任何"对象."前缀,所以其函数内部this指向的是window。因为所有回调函数都不是我们主动调用的,而是主函数自己根据情况而反复调用,其中
this
应固定不变,如果回调函数中的this不是想要的,都要用.bind()替换其中的this。
call apply bind 总结:
相同点:
- 都可以改变函数内部的this指向
- 第一个参数都是指定函数内部中this的指向
区别:
- call和apply会调用函数,bind 不会调用函数,但bind会创建一个和原函数一模一样仅仅改变了this的指向的新函数,然后在需要的时候调用新函数执行。
- call,apply和bind传递的参数不同,call和bind调用时接收的是指定的参数列表,apply调用时接收的是一个数组,apply可以打散其接收到的数组成为单个值,再分别传给函数实参。