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

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 博大精深。我就不一一举例了。了解了区别后,就全靠自己摸索了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值