JS中call()和apply()以及bind()的区别
一,方法定义
- apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
- call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
- bind:bind 除了返回是函数以外,它 的参数和 call 一样。
二,功能
bind/apply/call都会改变函数调用时this的指向
三,区别
1,执行方式
apply/call会立即执行该函数,bind是返回绑定this指向后的函数
2,参数
apply/call/bind第一个参数用于this指向改变后的对象
apply其余参数使用数组包裹参数
bind/call参数直接传递
四,比较
let obj ={
name:'obj中的name',
print(a,b,c){
console.log(this.name,a,b,c);
}
}
window.name = 'window中的name';
obj.print('1','2','3')
obj.print.apply(this,['1','2','3'])
obj.print.call(this,'1','2','3')
obj.print.bind(this,'1','2','3')() //必须带上(),因为bind()返回的是函数
// 结果
obj中的name 1 2 3
window中的name 1 2 3
window中的name 1 2 3
window中的name 1 2 3
本来print中的this指向调用者obj,但apply,call,bind将this指向全局作用域中的this(即window)
bind()
/**
* bind()
* bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值,
* 例如:f.bind(obj),实际上可以理解为obj.f(),这时f函数体内的this自然指向的是obj;
*/
var a = {
b: function() {
var func = function() {
console.log(this.c);
}
func();
},
c: 'hello'
}
a.b(); // undefined 这里的this指向的是全局作用域,在非严格模式下即window,严格模式下undefined
console.log(a.c); // hello
// 使用bind方法一
var a = {
b: function() {
var func = function() {
console.log(this.c);
}.bind(this);
func();
},
c: 'hello'
}
a.b(); // hello
console.log(a.c); // hello
// 使用bind方法二
var a = {
b: function() {
var func = function() {
console.log(this.c);
}
func.bind(this)();
},
c: 'hello'
}
a.b(); // hello
console.log(a.c); // hello
如果对一个函数进行多次 bind,那么上下文会是什么呢?
let a = {};
let fn = function () {
console.log(this);
};
fn.bind().bind(a)(); // => ?
不管我们给函数 bind 几次,fn 中的 this 永远由第一次 bind 决定,所以结果是 window。
另外, 在 ES6 的箭头函数下, call 和 apply 将失效,因为箭头函数的特点:
1,体内的 this 对象, 就是定义时所在的对象, 而不是使用时所在的对象
2,箭头函数不可以当作构造函数来用,也就是说不可以使用 new 命令, 否则报错
3,箭头函数不可以使用 arguments 对象,该对象在函数体内不存在,可以用 Rest 参数代替
4,不可以使用 yield 命令, 因此箭头函数不能用作 Generator 函数

浙公网安备 33010602011771号