bind,call,apply的区别

这是一道经典的面试题了。然鹅我一直都不知道他们三者区别。。。
所以今天学习下。

首先,他们三者都是改变this指向的。
在react当中,常常看到以下场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
handleFn(id = 0) {
console.log(id)
}

handleClick(id) {
// do something...
this.handleFn(id)
}

render() {
const list = [
{id: 1, name: '1'},
{id: 2, name: '2'}
]
return (
<ul>
{
list.map(item => <li key={item.id} onClick={this.handleClick.bind(this, item.id)}>{item.id}</li>)
}
</ul>
)
}

这是一个很常见的使用方法了,假如上面li的点击,不通过bind去绑定this,那么在函数handleClick中,this会为undefined。现在通过bind去改变this指向来避免handleClick中的this为空。

正常来说onClick中需要接收一个函数。所以假如用handleFn代替handleClick那么上面的写法就是:

1
list.map(item => <li key={item.id} onClick={this.handleFn}>{item.id}</li>)

也就是说this.handleClick.bind(this, item.id)这里返回的是一个函数。
而它的第一个参数为this指向的对象,后面则为多个参数this.handleClick.bind(this, arg1, arg2, ..., argx)

bind不同,call以及apply则是直接调用方法。而callapply之间的区别就是接收参数不一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
var name = '小红',
age = 22,
work = '扫地';

var obj = {
fn() {
console.log(`${this.name}今年${this.age}岁,做${this.work}${arg1}${arg2}`)
}
}

obj.fn.call(window, '热爱生活', '为人诚实') // 小红今年22岁,做扫地,热爱生活,为人诚实

obj.fn.apply(window, ['喜欢打球', '乐于助人']) // 小红今年22岁,做扫地,喜欢打球,乐于助人

可以从上述例子看到,callapply都是直接调用方法。apply将所有参数,以数组的形式放在第二个参数上;而call则跟bind一样排列放置参数。


总结:

方式返回参数格式
bind改变指向后的函数this, arg1, arg2, …, argx
callthis, arg1, arg2, …, argx
applythis, [arg1, arg2, …, argx]

参考文章:

https://www.runoob.com/w3cnote/js-call-apply-bind.html


bind,call,apply的区别
作者
墨陌默
发布于
2020年12月22日
许可协议