您的位置:首页 > 移动开发

Javascript中call(),apply(),bind()的区别

2015-05-21 18:38 471 查看
call(thisObj,arg1,arg2...)、apply(thisObj,[arg1,arg2...])。这两个方法是每个函数原型对象上包含的方法。

call(thisObj,arg1,arg2...)和apply(thisObj,[arg1,arg2...])作用都是一样的,作用都是改变当前使用该方法的对象中的this的指向,指向调用方法中的thisObj。

两者的区别是:call中传入的参数是一个个列举出来的,为apply中传入的参数是以数组的形式列出的。

例如下面的例子:

window.num = 1;
var o = {num:2};                       this对象指向执行该代码的对象的拥有者。
function showNum () {
<span style="white-space:pre">	</span>alert(this.num);
}
showNum ();//结果为1,这里的this指向window
showNum.call(this);//结果为1,同上
showNum.call(window);//结果为1
showNum.call(o);//结果为2,现在this指向的是o,这里this的指向由原来的window变为了o
showNum.apply(o);//结果为2,同上。


bind方法

bind方法和call,apply方法类似。bind方法会创建一个函数的实例,这个实例的this值会被绑定到传递给bind的参数上

function a(y) {
return this.x + y;
};
var o = {
x:1;
}
var g = a.bind(o);
g(2);//3


可以看出函数a的this被绑定到了o上了,并返回了新的函数g,调用g时,a函数会被当做对象o的方法来被调用。

bind方法是将函数绑定到某个对象上,并且返回一个新的函数,传入的参数都将传入到被绑定的函数上。

bind方法的的一个有效的作用是解决 函数对象作为参数传递时 this丢失的问题
。例如下面的代码:

var person = {
name : "marry",
showName : function() {
alert(this.name);
}
}
setTimeout(person.showName,5000);//执行的结果为空


因为执行函数时,javascript引擎会创建一个临时变量,传入的参数值会被传入给临时变量,这时this就为global,而不是指向了person.

为了解决这个问题便可以用bind方法将函数封装起来,并返回封装后的函数对象。

var person = {
name:"marry",
showName : function() {
alert(this.name);
}
}
var boundFunc = <strong>person.showName.bind(person);</strong>
setTimeout(boundFunc,5000);


这样person.showName会被当做person的方法被调用。

下面来看看三者的区别

相似之处:

(1)都是用来改变函数的this对象的指向的。

(2)第一个参数都是this要指向的对象

(3)都可以利用后续参数传参

区别:

先看下面的例子

var marry = {
name : 'marry',
age: 29,
showName :function() {
alert(this.name + "," + this.age);
}
}
var kevin = {
name : 'kevin',
age: 21,
}

marry.showName();//显示结果为 marry,29
如何用marry的showName来显示kevin的信息呢。
marry.showName.call(kevin);
marry.showName.apply(kevin);
marry.showName.bind(kevin)();


直接调用marry.showName.bind(kevin)是不会有任何结果的,需要加上();

call和apply是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面需要()来进行调用。


下面通过例子来看下call和apply的区别

var marry = {
name : "marry",
age : 29,
show:function( gender,city) {
alert(this.name + ”,“ + this.age +"," +this.gender +"," + this.city);
}
}

var kevin = {
name : "kevin",
age :30
}
<strong>marry.show.call(kevin,"男","杭州");
marry.show.apply(kevin,["男","杭州"]);</strong>
从它们的调用方式可以看出,call后面的参数与show中的参数一一对应,而apply中的第二个参数是一个数组,数组中的参数与show中的

参数一一对应。

因为bind返回的是一个函数,所以在调用函数的时候仍然需要传递参数。

marry.show.bind(kevin)("男","杭州");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: