对于这三个概念经常混淆,它们的作用也不甚明了,总结一句话:
call()、apply()、bind() 都是用来重定义 this 这个对象的!
**
从示例看起

示例1:

  1. const obj = {
  2. age:25,
  3. name:"Tom",
  4. fun1(){
  5. console.log("name:" + this.age + "\nage:" + this.name)
  6. }
  7. }
  8. const fun2 = obj.fun1
  9. fun2()

输出结果:

  1. name:undefined
  2. age:undefined

分析原因:
fun()2 中的this指向了window

示例2:

  1. var age = 26, name = "Jerry"
  2. const obj = {
  3. age:25,
  4. name:"Tom",
  5. fun1(){
  6. console.log("name:" + this.age + "\nage:" + this.name)
  7. }
  8. }
  9. const fun2 = obj.fun1
  10. fun2()

输出结果:

  1. name:25
  2. age:Tom

分析原因:

  1. 定义的agename在全局作用域中,验证了示例1的分析原因

提出疑问,如果我还想让fun2中的this指向obj呢,那这么办,这时候就用到这三个关键字了

示例3

我们重新修改一下程序

  1. var age = 26, name = "Jerry"
  2. const obj = {
  3. age:25,
  4. name:"Tom",
  5. fun1(){
  6. console.log("name:" + this.age + "\nage:" + this.age)
  7. }
  8. }
  9. const fun2 = obj.fun1
  10. fun2.apply(obj)
  11. fun2.call(obj)
  12. fun2.bind(obj)()

输出结果:

  1. name:25
  2. age:Tom
  3. name:25
  4. age:Tom
  5. name:25
  6. age:Tom

分析原因:

  1. bindcallapply更改了this的指向,因此输出了obj的属性

再次提出疑问,apply、call与bind的区别是什么

示例4

仔细观察我们在示例3中bind的用法,我们再次修改程序

  1. var age = 26, name = "Jerry"
  2. const obj = {
  3. age:25,
  4. name:"Tom",
  5. fun1(){
  6. console.log("name:" + this.age + "\nage:" + this.name)
  7. }
  8. }
  9. const fun2 = obj.fun1
  10. fun2.apply(obj)
  11. fun2.call(obj)
  12. const fun3 = fun2.bind(obj)
  13. fun3()

输出结果:

  1. name:25
  2. age:Tom
  3. name:25
  4. age:Tom
  5. name:25
  6. age:Tom

分析原因:

  1. 也就是说使用了applycall则立刻就执行了该函数,而bind只是绑定了this对象,绑定后的函数内的this不再改变

明白了apply、call与bind之前的区别了,那apply与call的区别是什么呢?

示例5

我修改obj对象的函数,使其带有参数

  1. var age = 26, name = "Jerry"
  2. const obj = {
  3. age:25,
  4. name:"Tom",
  5. fun1(gender,address){
  6. console.log("name:" + this.age + "\nage:" + this.name)
  7. console.log("gender:" + gender + "\naddress:" + address)
  8. }
  9. }
  10. const fun2 = obj.fun1
  11. fun2.apply(obj,["male","America"])
  12. fun2.call(obj,"male","Canada")
  13. fun2.bind(obj,"male","Africa")()

输出结果:

  1. name:25
  2. age:Tom
  3. gender:male
  4. address:America
  5. name:25
  6. age:Tom
  7. gender:male
  8. address:Canada
  9. name:25
  10. age:Tomgender:male
  11. address:Africa

分析结果:

  1. apply第二个参数可以是数组,而callbind的参数则不必