对于这三个概念经常混淆,它们的作用也不甚明了,总结一句话:
call()、apply()、bind() 都是用来重定义 this 这个对象的!
**
从示例看起
示例1:
const obj = {age:25,name:"Tom",fun1(){console.log("name:" + this.age + "\nage:" + this.name)}}const fun2 = obj.fun1fun2()
输出结果:
name:undefinedage: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.fun1fun2()
输出结果:
name:25age: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.fun1fun2.apply(obj)fun2.call(obj)fun2.bind(obj)()
输出结果:
name:25age:Tomname:25age:Tomname:25age: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.fun1fun2.apply(obj)fun2.call(obj)const fun3 = fun2.bind(obj)fun3()
输出结果:
name:25age:Tomname:25age:Tomname:25age: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.fun1fun2.apply(obj,["male","America"])fun2.call(obj,"male","Canada")fun2.bind(obj,"male","Africa")()
输出结果:
name:25age:Tomgender:maleaddress:Americaname:25age:Tomgender:maleaddress:Canadaname:25age:Tomgender:maleaddress:Africa
分析结果:
apply第二个参数可以是数组,而call和bind的参数则不必
