对于这三个概念经常混淆,它们的作用也不甚明了,总结一句话:
call()、apply()、bind() 都是用来重定义 this 这个对象的!
**
从示例看起
示例1:
const obj = {
age:25,
name:"Tom",
fun1(){
console.log("name:" + this.age + "\nage:" + this.name)
}
}
const fun2 = obj.fun1
fun2()
输出结果:
name:undefined
age:undefined
分析原因:
fun()2 中的this指向了window
示例2:
var age = 26, name = "Jerry"
const obj = {
age:25,
name:"Tom",
fun1(){
console.log("name:" + this.age + "\nage:" + this.name)
}
}
const fun2 = obj.fun1
fun2()
输出结果:
name:25
age:Tom
分析原因:
定义的age和name在全局作用域中,验证了示例1的分析原因
提出疑问,如果我还想让fun2中的this指向obj呢,那这么办,这时候就用到这三个关键字了
示例3
我们重新修改一下程序
var age = 26, name = "Jerry"
const obj = {
age:25,
name:"Tom",
fun1(){
console.log("name:" + this.age + "\nage:" + this.age)
}
}
const fun2 = obj.fun1
fun2.apply(obj)
fun2.call(obj)
fun2.bind(obj)()
输出结果:
name:25
age:Tom
name:25
age:Tom
name:25
age:Tom
分析原因:
bind、call、apply更改了this的指向,因此输出了obj的属性
再次提出疑问,apply、call与bind的区别是什么
示例4
仔细观察我们在示例3中bind的用法,我们再次修改程序
var age = 26, name = "Jerry"
const obj = {
age:25,
name:"Tom",
fun1(){
console.log("name:" + this.age + "\nage:" + this.name)
}
}
const fun2 = obj.fun1
fun2.apply(obj)
fun2.call(obj)
const fun3 = fun2.bind(obj)
fun3()
输出结果:
name:25
age:Tom
name:25
age:Tom
name:25
age:Tom
分析原因:
也就是说使用了apply和call则立刻就执行了该函数,而bind只是绑定了this对象,绑定后的函数内的this不再改变
明白了apply、call与bind之前的区别了,那apply与call的区别是什么呢?
示例5
我修改obj对象的函数,使其带有参数
var age = 26, name = "Jerry"
const obj = {
age:25,
name:"Tom",
fun1(gender,address){
console.log("name:" + this.age + "\nage:" + this.name)
console.log("gender:" + gender + "\naddress:" + address)
}
}
const fun2 = obj.fun1
fun2.apply(obj,["male","America"])
fun2.call(obj,"male","Canada")
fun2.bind(obj,"male","Africa")()
输出结果:
name:25
age:Tom
gender:male
address:America
name:25
age:Tom
gender:male
address:Canada
name:25
age:Tomgender:male
address:Africa
分析结果:
apply第二个参数可以是数组,而call和bind的参数则不必