JavaScript中call,apply,bind方法的总结

var a = {
    user:"bing",
    fn:function(){
        console.log(this.user); //bing
    }
}
a.fn()    //返回"bing"

var b = a.fn;
b();      //返回undefined  (this指向调用它的方法b,即window对象)

如果对以上代码的返回值有疑惑的,请看 彻底理解JavaScript中this指向

虽然a.fn()方法可以正常返回,但是有时候我们不得不将这个对象保存到另外的一个变量中,那么就可以通过以下方法。


用法

call()

通过在call方法,给第一个参数添加要把b添加到哪个环境中,简单来说,this就会指向那个对象。

var a = {
    user:"bing",
    fn:function(){
        console.log(this.user); 
    }
}
var b = a.fn;
b();  // undefined     (this指向window)
b.call(a);   //bing    (将b的this指针由window指向a)

apply()

apply方法和call方法有些相似,它也可以改变this的指向

var a = {
    user:"bing",
    fn:function(){
        console.log(this.user); //bing
    }
}
var b = a.fn;
b.apply(a);

同样apply也可以有多个参数,但是不同的是,第二个参数必须是一个数组,如下:

var a = {
    user:"bing",
    fn:function(i,j){
        console.log(this.user); //bing
        console.log(i+j); //33
    }
}
var b = a.fn;
b.apply(a,[11,22]);

注:如果call和apply的第一个参数写的是null,那么this指向的是window对象,如下:

var a = {
    user:"bing",
    fn:function(){
        console.log(this); //返回Window对象
    }
}
var b = a.fn;
b.apply(null);

tips: apply小应用

// 因为
Math.max(5,7,9,3,1,6)); // 9 

// 所以获取数组中最大的值可以这么写
var arr=[5,7,9,3,1,6]; 
alert(Math.max.apply(null,arr)); // 9

bind()

bind方法和call、apply方法有些不同,但它们都可以用来改变this的指向。

与call、apply方法不同,bind方法返回的是一个修改过后的函数。

var a = {
    user:"bing",
    fn:function(){
        console.log(this.user);
    }
}
var b = a.fn;
b.bind(a);     //ƒ(){console.log(this.user);}

b.bind(a)();   //再执行一次  正常返回'bing'

同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。

var a = {
    user:"bing",
    fn:function(e,d,f){
        console.log(this.user); //bing
        console.log(e,d,f); //10 1 2
    }
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);

区别

call()、apply()、bind() 都是用来重定义 this 这个对象的(改变this指针)!

区别:

  1. bind 返回的是一个新的函数,必须调用它才会被执行。call、apply则是立即执行
  2. apply参数是数组,call、bind参数是arguments对象

1. bind 返回的是一个新的函数,必须调用它才会被执行

var name = 'xx',
    age = 20;
var obj = {
    name: 'bing',
    objAge: this.age,
    myFun: function () {
        console.log(this.name, this.age)
    }
}
var my = {
    name: 'bb',
    age: 100
}

console.log(obj.objAge); // 20       obj的this指向window
obj.myFun(); // 'bing' undefined     myFun的this指向obj

// 通过call、apply、bind,将myFun的this指向由obj改成my
obj.myFun.call(my); // 'bb' 100
obj.myFun.apply(my); // 'bb' 100
obj.myFun.bind(my)(); // 'bb' 100       

2. apply参数是数组,call、bind参数是arguments对象

var name = 'xx',
    age = 20;
var obj = {
    name: 'bing',
    objAge: this.age,
    myFun: function (from, to) {
        console.log(this.name, this.age, from, to)
    }
}
var my = {
    name: 'bb',
    age: 100
}

obj.myFun.call(my, '成都', '上海'); // 'bb' 100 '成都' '上海'
obj.myFun.apply(my, ['成都', '上海']); // 'bb' 100 '成都' '上海'
obj.myFun.bind(my, '成都', '上海')(); // 'bb' 100 '成都' '上海'
obj.myFun.bind(my, ['成都', '上海'])(); // 'bb' 100 ['成都', '上海'] undefined

总结

  • 三者都可以改变函数的 this 对象指向

  • 三者第一个参数都是 this 要指向的对象,如果如果没有这个参数或参数为 undefined 或 null,则默认指向全局 window

  • 三者都可以传参,但是 apply 是数组,而 call 是参数列表,且 apply 和 call 是一次性传入参数,而 bind 可以分为多次传入。

  • bind 是返回绑定 this 之后的函数,便于稍后调用;apply 、call 则是立即执行 。

  • bind()会返回一个新的函数,如果这个返回的新的函数作为构造函数创建一个新的对象,那么此时 this 不再指向传入给 bind 的第一个参数,而是指向用 new 创建的实例


其他

call 和 apply 哪个性能会好一些

call的性能要比apply好一些,尤其是传递给函数的参数超过3个时所以后期开发的时候,可以使用call多一些
(传参数3个以内的话,call和apply性能差不多,超过3个以上call更好一些)

大概因为,apply 的第二个参数是数组,函数在执行时,解析数组获取参数,需要耗费性能。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫老板的豆

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值