call()/apply()是立即调用函数,都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。
一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向。
不同点:接收参数的方式不同
- apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
语法:apply([thisObj [,argArray] ]);
,调用一个对象的一个方法,另一个对象替换当前对象。
说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个
TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。
- call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。
语法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);
,应用某一对象的一个方法,用另一个对象替换当前对象。
说明: call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。
当没有使用call方法时:
<script>
var obj={username:'xue'};
function foo() {
console.log(this);
}
foo();
</script>
this就是指向window。
当使用call方法时:
foo.call(obj);
this就指向了我给它的对象
当使用apply时:
foo.call(obj); foo.apply(obj);
结果一模一样。
区别:传参
<script>
var obj={username:'xue'};
function foo(data) {
console.log(this,data);
}
foo.call(obj,33); //直接从第二个参数开始,依次传入
foo.apply(obj,[33]); //第二个参数必须是数组,参数放在数组里
</script>
如果apply相call那样传参的话,就会报错,以上才是正确模式,控制台输出一模一样。
bind
var obj={username:'xue'};
function foo(data) {
console.log(this,data);
}
foo.bind(obj);
这样写,控制台什么都不输出,bind的特点:绑定完this不会立即调用当前的函数,而是将函数返回
var bar=foo.bind(obj);
console.log(bar);
返回的是一个函数,如果让函数立即执行就这样写:
foo.bind(obj)();
bind传参:
bind传参的方式同call一样
foo.bind(obj,33)();
call、apply、bind三者的区别
call和apply指定了this,它会立即调用当前的函数,而bind不会立即调用函数,是把函数返回,bind通常用它来指定回调函数的this:
比如:
setTimeout(function () {
console.log(this);
}.bind(obj),1000);
如果不使用bind那么this指向的就是window,使用了bind,this就会指向这个obj。