JavaScript的那些坑之call,apply,bind

来源:互联网 发布:开票软件v2.0 编辑:程序博客网 时间:2024/06/06 02:04

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

而每个函数不用继承就拥有的方法都有两个: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));    //20console.log(callSum2(10,10));    //20console.log(callSum3(10,10));    //20

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

call()和apply()的作用

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

window.color="red";var o={ color:"bule"};function sayColor(){alert(this.color);}sayColor();            //redsayColor.call(this);   //redsayColor.call(window); //redsayColor.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。

1 0
原创粉丝点击