欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JS进阶 - apply , call, bind 用法和区别

程序员文章站 2022-07-14 14:27:40
...

JS中最常见的 applycallbind 用法和区别

三者区别

1. 调用的区别

applycall 会立即调用
bind 不会立即调用,而是返回一个函数

2. 传递参数的区别

  • 三个方法的第一个参数都是 要指向的对象 因为这3个方法都是用于修改this的指向。或者是绑定新的参数
  • 而且 apply 。接收的第二个参数是一个数组,没有第三个参数了
  • callbind 从第二个参数开始 可以接收N个参数,并没有限制

实例演示

文字不太好理解。附上代码那就差不多了

apply 示例

  • 无参,只修改this指向
  var Jioho = {
    id: 1,
    name: 'Jioho',
    say: function () {
      console.log(`Hello I'm ${this.name}.`)
    }
  }
  var Laiching = {
    id: 2,
    name: 'Laiching',
  }
  Jioho.say.apply(Laiching); // Hello I'm Laiching.
  • 有参,也是修改this指向
  var Jioho = {
    id: 1,
    name: 'Jioho',
    home:'DongGuang'
    say: function (sex, age) {
      console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
      console.log(this);
    }
  }
  var Laiching = {
    id: 2,
    name: 'Laiching',
    home:'DongGuang'
  }
  Jioho.say.apply(Laiching, ['girl', 3]); // Hello I'm Laiching.I'm a girl.I'm 3 years old.

注意传参地方,传的是一个数组 ['girl',3].
注意看第12行。在Jioho对象中是没有定义 home 这个属性的。而 Laiching 的对象中有这个属性。 用了apply或者其他后。home也会带上,可以注意观察 第 7 行的打印结果

call 示例

  • 无参,只修改this指向
  var Jioho = {
    id: 1,
    name: 'Jioho',
    say: function () {
      console.log(`Hello I'm ${this.name}.`);
      console.log(this)
    }
  }
  var Laiching = {
    id: 2,
    name: 'Laiching',
    home:'DongGuang'
  }
  Jioho.say.call(Laiching); // Hello I'm Laiching.
  • 有参,也是修改this指向
  var Jioho = {
    id: 1,
    name: 'Jioho',
    say: function (sex, age) {
      console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
      console.log(this)
    }
  }
  var Laiching = {
    id: 2,
    name: 'Laiching',
    home:'DongGuang'
  }
  Jioho.say.call(Laiching, 'girl', 3); // Hello I'm Laiching.I'm a girl.I'm 3 years old.
  Jioho.say.call(Laiching, ...['girl', 3]); // Hello I'm Laiching.I'm a girl.I'm 3 years old.

call 和 apply 用法其实都类似,都把 home 属性给带上了。也改变了this指向。只是传的参数不一样
call 接收的是一长串的参数,当然也可以用 es6 的解构来实现参数传一长串属性。

bind 示例

  • 无参,只修改this指向
  var Jioho = {
    id: 1,
    name: 'Jioho',
    say: function () {
      console.log(`Hello I'm ${this.name}.`);
      console.log(this)
    }
  }
  var Laiching = {
    id: 2,
    name: 'Laiching',
    home:'DongGuang'
  }
  Jioho.say.bind(Laiching);
  // ƒ(sex, age) {
  // console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
  // console.log(this);
  // }
  • 有参,修改this指向。传入参数。返回新的函数
    var Jioho = {
    id: 1,
    name: 'Jioho',
    say: function (sex, age) {
      console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)

      console.log(this);
    }
  }
  var Laiching = {
    id: 2,
    name: 'Laiching',
    age: 100
  }

  var Laiching_obj = Jioho.say.bind(Laiching);
  console.log(Laiching_obj);
  // ƒ(sex, age) {
  // console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
  // console.log(this);
  // }

  Laiching_obj('girl', 10); // Hello I'm Laiching.I'm a girl.I'm 10 years old.

bind 和 call 传递参数的方法是一致的,唯一不同的就是把函数直接返回回来,而并不执行
bind 是用于实现 蹦床函数 的核心要点。
传送门 : 蹦床函数实现

总结

每个方法存在肯定有他的道理。优化传参步骤和修改this指向,用法实在太多,可以在实际使用中慢慢积累经验.

三个函数的基础作用都是修改 this 的指向问题。或者为对象添加新的属性

更进阶的用法呢?

 // 现在有一个 f 方法。接收3个参数
 function f(param1,param2,param3){
    // do somthing
 }
 
 // 而你的参数都在一个数组中
 var params = [1,2,4];
 
 // 这时候为了传参方便。就可以使用apply了
 f.apply(null,params);
 
 // 而 es6 新出的语法也可以代替 apply了。效果都是一样的
 f(...params);
 

JS 博大精深。我就不一一举例了。了解了区别后,就全靠自己摸索了

相关标签: apply call bind