在javascript中call、apply与bind都用于改变this绑定
- bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 ;
var name = "window";
let obj1 = {
name: "Mitty"
}
let obj2 = {
name: 'Jim'
}
function fn(addr) {
console.log(this.name + '在' + addr);
}
// 这里的this指向的是 window
fn('浏览器'); // window在浏览器
// 改变this指向, apply、call立即调用
fn.apply(obj1, ['上海']); // Mitty在上海
fn.call(obj1, '上海'); // Mitty在上海
// bind 是返回对应函数
let bindFn = fn.bind(obj1);
bindFn('上海') // Mitty在上海
- apply、call再次调用时需要重新绑定; bind绑定后可以一直调用,强绑定;
// apply、call和bind的区别
// apply、call再次调用时需要重新绑定
fn.apply(obj1, ['上海']); // Mitty在上海
fn.call(obj1, '上海'); // Mitty在上海
// bind绑定后可以一直调用,强绑定
bindFn('上海') // Mitty在上海
// 并且无法再次更改this指向,尝试为将bind绑定后的函数重新改变到obj2
bindFn.apply(obj2, ['北京']); // Mitty在北京
bindFn.call(obj2, '北京'); // Mitty在北京
bindFn.bind(obj2)('北京'); // Mitty在北京
fn.apply(obj2, ['北京']); // Jim在北京
fn.call(obj2, '北京'); // Jim在北京
fn.bind(obj2)('北京'); // Jim在北京
总结
- call、apply与bind都用于改变this绑定,但call、apply在改变this指向的同时还会执行函数,而bind在改变this后是返回一个全新的boundFcuntion绑定函数,这也是为什么上方例子中bind后还加了一对括号 ()的原因。
- bind属于硬绑定,返回的 boundFunction 的 this 指向无法再次通过bind、apply或 call 修改;call与apply的绑定只适用当前调用,调用完就没了,下次要用还得再次绑。
- call与apply功能完全相同,唯一不同的是call方法传递函数调用形参是以散列形式,而apply方法的形参是一个数组。在传参的情况下,call的性能要高于apply,因为apply在执行时还要多一步解析数组。