JavaScript 进阶营JavaScript

js中call、bind、apply你知多少?

2019-06-21  本文已影响0人  王一诺Eno

@TOC

在我们日常开发过程中call、bind、apply无疑是我们用的比较多的语法,今天在开发中看到有同事傻傻分不清call和bind的区别,故在解释一通之后,写下此文;

首先查看文档理解含义

call()

MDN 文档 call我们可以了解到:
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

先举个例子:

// main.js
  const foo={
      name:'foo',
      getFoo(...args){
        console.log('this===',this,'this.name==',this.name)
        console.log('-----------------------------------')
        console.log('...args=====',...args)
      }
    }
    const bar={
      name:'bar',
      getBar(...args){
        console.log('this===',this,'this.name==',this.name)
        console.log('-----------------------------------')
        console.log('...args=====',...args)
      }
    }
    foo.getFoo() //this=== {name: "foo", getFoo: ƒ} this.name== foo  ----------------------------------- ...args=====
    bar.getBar() //this=== {name: "bar", getBar: ƒ} this.name== bar  ----------------------------------- ...args=====

假如我们想在getFoo去借bar里面的东西用用,该怎么办呢?
也许有同学想到的是这样:

    foo.getFoo(bar.name) // this=== {name: "foo", getFoo: ƒ} this.name== foo -----------------------------------  ...args===== bar

毫无疑问,这是没问题的,但此时只是正常的传参,能否干脆点把this.name也改成bar呢;根据call的定义:

foo.getFoo.call(bar,'测试传参','测试call') //his=== {name: "bar", getBar: ƒ} this.name== bar ----------------------------------- ...args===== 测试传参 测试call
//使用call后,我们可以看到foo.getFoo的this此时指向了bar对象,此时的name拿到的bar的对象的name;

apply()

MDN 文档 apply我们可以了解到:
apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。

继续使用刚才的foo和bar

foo.getFoo.apply(bar,['测试传参','测试apply']) //his=== {name: "bar", getBar: ƒ} this.name== bar ----------------------------------- ...args===== 测试传参 测试apply

总结 call方法和apply方法两者极度相似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。

bind()

MDN 文档 bind我们可以了解到:

bind()方法创建一个新的函数,在调用时设置this关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。

emmmm...继续最最上面的那个foo和bar

foo.getFoo.bind(bar,'测试传参','测试bind') // 此时是无输出,因为bind()方法创建一个新的函数,当前函数并没有执行


修改如下:

const foobindbar = foo.getFoo.bind(bar,'测试传参','测试bind');

console.log(foobindbar)
    // ƒ getFoo(...args){
    //   console.log('this===',this,'this.name==',this.name)
    //   console.log('-----------------------------------')
    //   console.log('...args=====',...args)
    // }

foobindbar() //this=== {name: "bar", getBar: ƒ} this.name== bar ----------------------------------- ...args===== 测试传参 测试apply


总结

call和apply的区别

call方法和apply方法两者极度相似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。用apply时,即使传入的参数只有一个,也必须定义为数组才行;

call与apply 和 bind的区别

call与apply改变this的指向时,会直接触发函数;而bind会创建一个新的函数,在调用时设置this关键字为提供的值,使用bind时,会优先使用bind绑定的几个值;
如下:

foo.getFoo.bind(bar,'测试传参','测试bind')
const foobindbar = foo.getFoo.bind(bar,'测试传参','测试bind');

console.log(foobindbar)
    // ƒ getFoo(...args){
    //   console.log('this===',this,'this.name==',this.name)
    //   console.log('-----------------------------------')
    //   console.log('...args=====',...args)
    // }

foobindbar('参数1', '参数2') //this=== {name: "bar", getBar: ƒ} this.name== bar ----------------------------------- ...args=====  测试传参 测试apply 参数1 参数2
// ...args=====  测试传参 测试apply 参数1 参数2

文章所示demo请转王一诺/github

上一篇 下一篇

猜你喜欢

热点阅读