结论
方法名 | 参数 | 函数立即执行一次 | 返回新函数 |
---|---|---|---|
call | 单个按顺序传参 | 是 | 否 |
apply | 数组形式传参 | 是 | 否 |
bind | 单个形式传参 | 否 | 是 |
因为bind不会立即执行,所以和回调函数是绝配
call
- 场景
函数get想要获取一个对象 lilei 的属性 this.name ,但是函数默认的this是指向window的,所以获取不到this.name这个值。
解决办法:使用call将函数get默认的this指向对象 lilei。
- code
function get(age,money) {
console.log(this.name,age,money)
}
let lilei = {name:"lilei"}
get.call(lilei,20,2000) // output: lilei 20 2000
- 特性
- 调用call时,会立即执行一次函数
- 第一个实参代表this,替换一次
- 第二个实参往后,是传给function的参数
apply
- 场景
函数get想要获取一个对象 lilei 的属性 this.name ,但是函数默认的this是指向window的,所以获取不到this.name这个值。
解决办法:使用apply将函数get默认的this指向对象 lilei。
- code
function get(age,money) {
console.log(this.name,age,money)
}
let lilei = {name:"lilei"}
let arr = [20,2000]
get.apply(lilei,arr) // output: lilei 20 2000
- 特性
- 调用apply时,会立即执行一次函数
- 第一个实参代表this,替换一次
- 第二个实参必须是数组,apply回自动打散数组,作为function的参数
bind
- 场景
需要反复调用this的情况下,call和apply就显得不太合适,会产生大量重复的代码。
解决办法:使用bind直接复制函数模板给新的函数,并且可以设定以一个固定的参数
- code
function get(age,money) {
console.log(this.name,age,money)
}
let lilei = {name:"lilei"}
let newFun = get.bind(lilei,20)
newFun(2000) // output: lilei 20 2000
newFun(3000) // output: lilei 20 3000
- 场景2
bind和回调函数是绝配,因为call和apply会立即执行,而且没有返回值。
bind不会立即执行,也会返回一个新的函数。
下面使用一个定时器模拟异步请求
- code
let lilei = {name:"lilei"}
setInterval(function get (age,money) {
console.log(this.name,age,money)
}.bind(lilei,20,2000),2000) // output: 间隔两秒输出一次lilei 20 2000
- 特性
- bind会返回一个新的函数模板,并且不会立即执行
- 第一个实参永久替换this
- 允许第二个之后的实参,为固定值