apply call bind的区别
apply、call、bind都是用来改变函数调用时this的指向的方法,它们的区别可以从以下几个方面来讲。
1. 参数传递的形式
call和apply的区别在于参数传递的形式不同,call方法的参数是依次传递的,而apply方法的参数是以数组的形式传递的。
例如:
function fn(a, b) {
console.log(this, a, b);
}
fn.call('hello', 1, 2); // 输出:hello 1 2
fn.apply('world', [3, 4]); // 输出:world 3 4
bind方法则是返回一个新函数,原函数的this指向被改变为bind方法传入的 个参数,后续传入的参数会被保存在新函数中,调用新函数时会将它们传递给原函数。
例如:
var obj = {
name: 'Mike'
};
function fn() {
console.log(this.name, arguments);
}
var newFn = fn.bind(obj, 1, 2); // 此时参数已经被保存在newFn中
newFn(3, 4); // 输出:Mike [1, 2, 3, 4]
2. 返回值
call和apply方法在调用函数时会立即执行,并且返回函数的执行结果。而bind方法返回的是一个新函数,需要调用这个新函数才会执行原函数。
例如:
function fn() {
return this.name;
}
var obj1 = { name: 'Mike' };
var obj2 = { name: 'Jack' };
var result1 = fn.call(obj1);
console.log(result1); // 输出:Mike
var result2 = fn.apply(obj2);
console.log(result2); // 输出:Jack
var newFn = fn.bind(obj1);
var result3 = newFn();
console.log(result3); // 输出:Mike
3. 定义方式
call和apply是直接作为函数对象方法进行调用的,而bind作为Function对象的原型方法进行调用。
例如:
var obj = {
name: 'Mike',
fn: function() {
console.log(this);
}
};
obj.fn.call(obj); // 输出:Object { name: "Mike", fn: function() {...} }
obj.fn.apply(obj); // 输出:Object { name: "Mike", fn: function() {...} }
var newFn = obj.fn.bind(obj);
newFn(); // 输出:Object { name: "Mike", fn: function() {...} }
结论
总结来说,apply、call、bind的区别可以简述如下:
- apply和call方法用来改变函数调用时this的指向,方法参数传递形式不同
- bind方法也用来改变函数调用时this的指向,但不会立即执行原函数,而是返回一个新函数,参数传递同call方法
- call和apply会立即执行原函数并返回函数执行结果,而bind返回的是一个新函数,需要再次调用才会执行原函数
- apply和call作为函数对象方法进行调用,而bind作为Function对象原型方法进行调用
