apply、call和bind
在js中,每个函数都包含两个非继承而来的方法:apply和call。ECMAScript 5 定义了bind()方法。它们能够扩充函数赖以运行的作用域,用途是在特定的作用域中调用函数。
apply
这个方法接收两个参数。第一个是在其中运行函数的作用域,另一个是参数数组(arguments或Array实例)。
var color='red'; function sayColor(name,color){ return name+',this is '+color; } function colorFn(name){ var color='blue'; return sayColor.apply(this,[name,this.color]); }
alert(colorFn('mary'));//Mary,this is red
在上面这个例子中,colorFn在执行sayColor函数是传入的this作为this值(因为是在全局作用域中调用,传入的就是window对象)。
call:
call()方法与apply()方法作用相同。第一个参数没有变化,区别在于第二个参数不用数组传递,而是将参数逐个列举出来。
function sum(x,y) { return x+y; } function callSum(x,y){ return sum.call(this,x,y); } alert(callSum(1,2));//3
call()和apply的选择,取决于采用哪种给函数传递参数的方式最方便。
作用域:
var color='red'; var obj={ color:'green' } function sayColor(){ return this.color; } alert(sayColor.call(window));//red alert(sayColor.call(obj));//green alert(sayColor.call(this));//red
从上面的例子可以看到,同一个函数,但是根据参数的不同,执行环境已经发生了改变。
优点:
使用call()或apply()最大的好处就是对象不需要域方法有任何耦合关系。我们不需要将sayColor再放到对象obj中,然后通过obj来调用它了。
bind:
var color='red'; var obj={ color:'green' } function sayColor(){ return this.color; } var objColor=sayColor.bind(obj); alert(objColor());//green
bind会返回一个函数。
function sum(x,y){return x+y;}function callSum(x,y){return sum.call(this,x,y);}alert(callSum(1,2));//3