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();
总结
call
、apply
、bind
方法的共同点和区别:
相同:
都是用来改变函数的this对象的指向的;
第一个参数都是this要指向的对象,也就是想指定的上下文(函数的每次调用都会拥有一个特殊值——本次调用的上下文(context)——这就是
this
关键字的值。);- 三者都可以利用后续参数传参;
不同:
目标函数调用call、apply后,会直接被执行
目标函数调用bind后不会被立即执行,而是返回一个新的函数,调用新函数才会返回目标函数
(即bind
是返回对应函数,便于稍后调用;apply
、call
则是立即调用 。 )
注意:
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,'安徽','苏州')();
![](https://img2020.cnblogs.com/blog/2580638/202110/2580638-20211015212250616-2138935030.png)