函数的call、apply以及bind的作用与区别

每个函数都包含两个非继承而来的方法: apply()call(), 这两个方法的用途就是在特定的作用域中调用函数,实际上就是设置函数体内this对象的值。

apply()

apply()接受两个参数,

  • 第一个就是指定运行函数的作用域(就是this的指向)
  • 第二个是参数数组,
    • Array实例
    • arguments对象
1
2
3
4
5
6
7
8
9
10
11
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() 需要列举所有传入的所有参数

1
2
3
4
5
6
7
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() 的真正强大的地方是能扩充作用域

1
2
3
4
5
6
7
8
9
10
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()函数的值

1
2
3
4
5
6
7
8
9
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

坚持原创技术分享,您的支持将鼓励我继续创作!