call、apply
一、作用
每个函数都包含两个方法,call() 和 apply();
在ES5中,this总是指向调用该函数的对象(这里不讨论ES6中的箭头函数this指向问题);
在特定的作用域内调用函数,并且改变该函数的this指向 ;
1.call
<script>
console.log(this); //window
window.color = 'red';
document.color = 'blue';
var color1 = {
color: 'orange'
}
function getColor(){
consolor.log(this.color);
}
getColor(); //'red'
// 以下均是执行 getColor 函数,只不过是改变了this的指向
getColor.call(); //this默认指向window 'red'
getColor.call(this); //this指向window 'red'
getColor.call(window); //this指向window ‘red’
getColor.call(document); //this指向document 'blue'
getColor.call(color1); //this指向color1 'orange'
//多个参数情况
var sum = {
a: 0,
b: 0,
getSum: function(c, d){
return this.a + this.b + c + d;
}
}
var s1 = {
a : 1,
b: 2
}
sum.getSum.call(s1, 3, 4); // 10
</script>
2. apply
<script>
function getColor(){
console.log(this.color);
}
window.color = 'red';
document.color = 'blue';
var color1 = {
color: 'orange'
}
getColor.apply();
getColor.apply(this); //this指向window 'red'
getColor.apply(window); //this指向window ‘red’
getColor.apply(document); //this指向document 'blue'
getColor.apply(color1); //this指向color1 'orange'
//多个参数情况
function getColor(color){
this.color = color;
this.get = function(){
console.log(this.color);
}
}
function setColor(color){
getColor.apply(this, arguments);
}
var set = new setColor('orange');
set.get(); //orange
</script>
二、区别
传递参数不同
call(this, 参数1, 参数2, 参数3, …)
apply(this,[参数1, 参数2, 参数3, …])
call()方法 和 apply()方法 唯一的区别就是传递参数不同,call()方法第一个参数是this,后面的参数必须一个一个的写出来,apply()方法第一个参数是this,后面跟了一个数组,参数都写在这个数组里面。
如果apply()方法后面参数不跟数组会怎么样呢?
会报错: Uncaught TypeError: CreateListFromArrayLike called on non-object
bind
一、作用
绑定函数,改变this指向
- 我们经常碰到这种情况,创建一个变量保存当前this
-
<script> var foo = { name: 'jiangfulai', click: function(){ var _this = this; document.body.onclick = function(){ console.log(_this.name); } } } foo.click(); //jiangfulai </script>
以上写法也可以,但是不够优雅,我们可以通过bind(),更优雅的写出这个代码
-
<script> var foo = { name: 'jiangfulai', click: function(){ document.body.onclick = function(){ console.log(this.name); }.bind(this); } } foo.click(); //jiangfulai </script>
二、区别
bind() 方法 和 call() 方法 、apply() 方法有一定的区别
- bind() 方法是返回对应的函数,需要自己调用。
- call() 方法、apply()方法是立即执行
-
微妙的差距!
call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:
call的参数是直接放进去的,第二第三第n个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,‘成都’, … ,‘string’ );
apply的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,[‘成都’, …, ‘string’ ]);
bind除了返回是函数以外,它 的参数和call 一样。
当然,三者的参数不限定是string类型,允许是各种类型,包括函数 、 object 等等!