JavaScript的那些坑之call,apply,bind

大家都知道,函数也是对象,所以函数也可以拥有属性和方法。

而每个函数不用继承就拥有的方法都有两个:apply()和call()。

call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。

因为 JavaScript 的函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

call()和apply()的不同

两个方法的作用完全一样,仅有的一个区别就是接受的参数方式不同。

首先,apply()方法接收两个参数:一个是其运行函数的作用域,另一个就是参数数组。这个参数数组可以是Array的实例,也可以是arguments对象。

call()方法,第一个参数没有变,变化的是其余的参数都直接传给函数。

function sum(num1,num2){
	return num1+num2;
}
function callSum1(num1,num2){
	return sum.apply(this,arguments);   //apply传arguments
}
function callSum2(num1,num2){
	return sum.apply(this,[num1,num2]); //apply传参数数组
}
function callSum3(num1,num2){
	return sum.call(this,num1,num2);    //call把参数直接都传给函数,必须明确把每一个参数。
}
console.log(callSum1(10,10));    //20
console.log(callSum2(10,10));    //20
console.log(callSum3(10,10));    //20

使用call()和apply()本质上没什么不同,至于使用call()还是apply()取决于你采取哪种给函数传递参数更方便。

call()和apply()的作用

但是,这两个方法真正的作用,也像前面说的,是改变函数模拟运行的作用域。

window.color="red";
var o={ color:"bule"};
function sayColor(){
	alert(this.color);
}
sayColor();            //red

sayColor.call(this);   //red
sayColor.call(window); //red
sayColor.call(o);      //blue

因为没有参数,所以call方法传递的只是执行的作用域而已,

因为sayColor()是作为全局函数定义的,所以对this.color的求值,也就变成了对window.color的求值,左右前三个都是red。

但是当传入了o这个参数的时候,函数的执行环境就变了,此时的函数的tihs对象就指向了o,所以也就输出了o.color--blue。

bind()方法

ECMAScript5还定义了一个bind()方法。call()和apply()方法的用途实在特定的作用域中调用函数,也就是设置函数中this的值。
而bind()方法则是会创建一个新的函数实例,不过也需要传递个bind()this的值。
window.color="red";
var o={ color:"bule"};
function sayColor(){
	alert(this.color);
}
var objectSayColor=sayColor.bind(o);
objectSayColor();   //blue

sayColor()调用了bind()并传入对象o,创建了objectSayColor()函数。这个函数的this值就等于o,因此即使在全局作用域调用这个函数,也会看到"blue"。
支持bind方法浏览器有IE9+、Firefox 4+、Safari 5.1+、Opera 12+和Chrome。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值