每个函数都包含两个非继承而来的方法: apply()
和call()
, 这两个方法的用途就是在特定的作用域中调用函数,实际上就是设置函数体内this对象的值。
apply()
apply()
接受两个参数,
- 第一个就是指定运行函数的作用域(就是this的指向)
- 第二个是参数数组,
- Array实例
- arguments对象
function sum(sum1, sum2) {
return sum1 + sum2
}
function sumApply1(sum1, sum2) {
return sum.apply(this, arguments) // 传如arguments对象
}
function sumApply2(sum1, sum2) {
return sum.apply(this, [sum1, sum2]) // 传入数组
}
console.log(sumApply1(10,20)) // => 30
console.log(sumApply2(10,20)) // => 30
上面的例子, sumApply1()
执行sum()
的时候传入了this
作为this
值(因为是在全局作用域中调用的, 所以this
指向window
对象)和arguments对象, 而sumApply2()
传入了this
和一个参数数组, 返回的结果是相同的;
call()
call()
方法和apply()
方法作用相同, 区别在于接收参数的方式不同, call()
需要列举所有传入的所有参数
function sum(sum1, sum2) {
return sum1 + sum2
}
function sumCall1(sum1, sum2) {
return sum.call(this, sum1, sum2)
}
console.log(sumCall1(10,20)); // => 30
apply()
和call()
的真正强大的地方是能扩充作用域
var color = 'red';
var o = {
color: 'blue'
}
function sayColor() {
console.log(this.color);
}
sayColor.call(this) // => red
sayColor.call(window) // => red
sayColor.call(o); // => blue
定义一个全局函数sayColor()
, 一个全局变量color='red'
和一个对象o
, 第一个sayColor.claa(this)
由于是在全局作用域调用的, 所以this
指向window
, this.color
就转换成了window.color
所以就是red
, 第二个同第一个, sayColor.call(o)
把执行环境改成了o
, 因此函数内的this
就指向了对象o
, 所以结果是blue
;
使用call()
或apply()
扩充作用域最大的好处厹, 对象不需要与方法有任何耦合关系,
bind()
这个方法会创建一个函数实例, 其this
的值指向传给bind()
函数的值
window.color = 'red'
var o = {
color: 'blue'
}
function sayColor() {
console.log(this.color)
}
var bindSayColor = sayColor.bind(o);
bindSayColor() // => blue
这里sayColor()
调用了bind()
并传入了参数o
, 创建了bindSayColor
函数, bindSayColor()
的this就指向了o
, 因此在全局作用域中调用这个函数, 也会指向o