js中的call()、apply()、bind()方法详解

 这三个方法都是 Function 对象自带的方法,挂载在 Function.prototype 上。都有一个共同的功能:改变this的指向,那么又是怎么改变的呢?接下来我们依次来分析这三个方法

  1、call()方法                                                                                                                             

    说明:传入多个参数,第一个是this的指向,之后的参数都是函数的参数。

    例如:B.call(A, args1,args2);即A对象调用B对象的方法。

 

    接下来我们来看一下call()方法的具体传值

function a(){
    console.log(this); //输出函数a中的this对象
}
function b(){} //定义函数b
 
var obj = {name:'onepixel'}; //定义对象obj
 
a.call(); //window
a.call(null); //window
a.call(undefined);//window
a.call(1); //Number
a.call(''); //String
a.call(true); //Boolean
a.call(b);// function b(){}
a.call(obj); //Object
    window.name = "window";
    p = {
        name : "Andy",
        age : 18
    }
    function say1(){
        console.log(this.name);
    }
    function say2(s1,s2){
        console.log("和是:" + (s1+s2));
    }
   say1(); //window say1.call(window);
//window say1.call(p); //Andy say2.call('',1,2); //和是3 被调用的对象可以没有

   上面这个例子当调用say1.call(p)时this指向就变了,如果只是say1()的话是默认绑定,this指向window,但是使用say1.call(p)之后变成了显示绑定,this指向了传入的第一个参数p

 

   下面这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4); 

function add(a,b)  {  
    alert(a+b);  
}  

function sub(a,b)  {  
    alert(a-b);  
}  

add.call(sub,3,1)

 

 实现继承,call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat

function Animal(){  
    this.name = "Animal";  
    this.showName = function(){  
        console.log(this.name);  
    }  
}  

function Cat(){  
    this.name = "Cat";  
}  

var animal = new Animal();  
var cat = new Cat();  

//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。  
animal.showName.call(cat); //Cat 
//animal.showName.apply(cat);

call 的核心功能,它允许你在一个对象上调用该对象没有定义的方法,并且这个方法可以访问该对象中的属性, 

 

  2、apply()方法

   说明:传入两个参数,第一个参数就是this的指向,第二个参数就是函数参数组成的数组。

 例如:B.apply(A, arguments);即A对象应用B对象的方法。

 apply()方法和call()方法十分类似,只需要注意第二个参数是数组就行,这里就不过多重复解释了

function p(x,y,z){
    console.log(x,y,z);
}
 
p.apply(null,[1,2,3]); // 1 2 3

 

  3、bind()方法

 说明:bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。

    注意:bind()方法的返回值是函数

var person=function(){
        console.log(this.x);
    }
    var p={
        x:3
    }
    person();//undefined
    person.bind(p)();//3
    /**/
    // var fun=person.bind(p);
    // fun();

 

总结

 callapplybind方法的共同点和区别:

 相同:

  • 都是用来改变函数的this对象的指向的; 
  • 第一个参数都是this要指向的对象,也就是想指定的上下文(函数的每次调用都会拥有一个特殊值——本次调用的上下文(context)——这就是this关键字的值。);
  • 三者都可以利用后续参数传参;

 不同:

  目标函数调用call、apply后,会直接被执行

  目标函数调用bind后不会被立即执行,而是返回一个新的函数,调用新函数才会返回目标函数  

   (即bind 是返回对应函数,便于稍后调用;applycall则是立即调用 。 )

   注意: 

  call() 、apply() 、 bind() 方法对于箭头函数来说只是传入参数,对它的 this 毫无影响

   最后我们对比一下call、apply、bind的传参情况

var obj = {
        name: '萌萌',
        age: this.age,
        myFun: function (come,walk){
            console.log(this.name + "年龄" + this.age + "从" + come + "去" + walk);
        }
    }
    var p = {
        name: "白白",
        age: 18
    }

    obj.myFun.call(p,'安徽','苏州');
    obj.myFun.apply(p,['安徽','苏州']);
    obj.myFun.bind(p,'安徽','苏州')();

 

posted @ 2021-10-15 21:25  打遍天下吴敌手  阅读(142)  评论(0编辑  收藏  举报