• 前端基础:call、apply、bind的基本概念


    一、call

    call是一个方法,是函数的方法

    1. function fun() {
    2. console.log('hello, guoyu')
    3. }
    4. // call 可以调用函数
    5. fun.call() // 输出 hello, guoyu
    1. function fun() {
    2. console.log(this.name)
    3. }
    4. let cat = {
    5. name: '喵喵'
    6. }
    7. // 上面两段代码,一点关系没有
    8. // 但我们可以通过一个call就可以建立起他们的关系
    9. // call可以调用函数,call可以改变函数中的this
    10. // 让函数中的this指向这个cat对象,本身函数中的this是指向window/global的
    11. fun.call(cat) // 喵喵

    看下面例子

    1. let dog = {
    2. name: '旺财',
    3. sayName: function() {
    4. console.log(`我是${this.name}`)
    5. }
    6. }
    7. let cat = {
    8. name: '喵喵'
    9. }
    10. dog.sayName() // 我是旺财
    1. function fun() {
    2. console.log(this.name)
    3. }
    4. let dog = {
    5. name: '旺财',
    6. sayName: function() {
    7. console.log(`我是${this.name}`)
    8. }
    9. }
    10. let cat = {
    11. name: '喵喵'
    12. }
    13. // dog.sayName() // 我是旺财
    14. // 如果我想实现喵喵怎么办,可是cat没有sayName这个方法啊
    15. // 可以使用call借用,让猫去用狗的方法
    16. dog.sayName.call(cat) // 我是喵喵

    上面都是简单的,如果再难点呢,比如,狗子里再加个eat方法,带有其他参数。

    1. let dog = {
    2. name: '旺财',
    3. sayName: function() {
    4. console.log(`我是${this.name}`)
    5. },
    6. eat: function(food1, food2) {
    7. console.log(`${this.name}喜欢吃${food1}${food2}`)
    8. }
    9. }
    10. let cat = {
    11. name: '喵喵'
    12. }
    13. dog.eat('骨头', '屎') //我喜欢吃骨头、屎
    14. // 如果猫想用这个方法呢, call的用法
    15. dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠

    二、apply

    apply和call的用法几乎是一样的,call第二个参数开始是参数列表,apply只是把这些参数整到一个数组中

    1. let dog = {
    2. name: '旺财',
    3. sayName: function() {
    4. console.log(`我是${this.name}`)
    5. },
    6. eat: function(food1, food2) {
    7. console.log(`${this.name}喜欢吃${food1}${food2}`)
    8. }
    9. }
    10. let cat = {
    11. name: '喵喵'
    12. }
    13. dog.eat('骨头', '屎') //我喜欢吃骨头、屎
    14. // 如果猫想用这个方法呢, call的用法
    15. dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠
    16. // 如果是apply,参数改成[数组]方式即可
    17. dog.eat.apply(cat, ['鱼', '老鼠'])

    三、bind

    bind和call有点不同,call会调用比如前面的eat函数,bind不会,bind返回的是一个函数,还需要再手动调用一次 。

    1. let dog = {
    2. name: '旺财',
    3. sayName: function() {
    4. console.log(`我是${this.name}`)
    5. },
    6. eat: function(food1, food2) {
    7. console.log(`${this.name}喜欢吃${food1}${food2}`)
    8. }
    9. }
    10. let cat = {
    11. name: '喵喵'
    12. }
    13. dog.eat('骨头', '屎') //我喜欢吃骨头、屎
    14. // 如果猫想用这个方法呢, call的用法
    15. dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠
    16. // 如果是apply,参数改成[数组]方式即可
    17. dog.eat.apply(cat, ['鱼', '老鼠'])
    18. const fun = dog.eat.bind(cat, '鱼', '老鼠')
    19. fun()

     四、call、apply、bind的实际应用

    实现继承

    1. // 继承:子类可以使用父类的方法
    2. function Animal() {
    3. this.eat = function() {
    4. console.log('吃东西')
    5. }
    6. }
    7. let ani = new Animal()
    8. ani.eat() // 吃东西
    9. // 下面的代码和上面毫无关系,并没有形成继承关系
    10. function Cat () { }
    11. let cat = new Cat()
    12. cat.eat() // 肯定会报错

     看看使用call方式实现继承

    1. // 继承:子类可以使用父类的方法
    2. function Animal() {
    3. // 自然而然这里的this也是指向小cat了----2
    4. // 那么this.eat 就是小cat.eat,那么小cat就有这个eat方法了
    5. this.eat = function() {
    6. console.log('吃东西')
    7. }
    8. }
    9. let ani = new Animal()
    10. ani.eat() // 吃东西
    11. // 如何才能让Cat继承Animal呢
    12. function Cat () {
    13. // Animal 是构造函数,它也是函数,就可以直接调call,就把this传进去
    14. // 已经实现了继承
    15. // 这里的this指向小cat----1
    16. Animal.call(this)
    17. }
    18. let cat = new Cat()
    19. cat.eat()

     而且call还可以实现多重继承

    1. // 继承:子类可以使用父类的方法
    2. function Animal() {
    3. // 自然而然这里的this也是指向小cat了----2
    4. // 那么this.eat 就是小cat.eat,那么小cat就有这个eat方法了
    5. this.eat = function() {
    6. console.log('吃东西')
    7. }
    8. }
    9. function Bird() {
    10. this.fly = function() {
    11. console.log('I can fly')
    12. }
    13. }
    14. let ani = new Animal()
    15. // 如何才能让Cat继承Animal呢
    16. function Cat () {
    17. // Animal 是构造函数,它也是函数,就可以直接调call,就把this传进去
    18. // 已经实现了继承
    19. // 这里的this指向小cat----1
    20. Animal.call(this)
    21. Bird.call(this)
    22. }
    23. let cat = new Cat()
    24. cat.eat()
    25. cat.fly()

  • 相关阅读:
    C++设计模式(Design Patterns)
    Python爬虫教程:如何爬取教育漏洞报告平台中的漏洞报告?
    【星海随笔】C++程序设计(实践)04738复习资料
    工业生产排污、海洋环境、生活用水检测——TFN TOC200M 总有机碳分析仪
    Java&Vue 借助json传递数据
    Dart(2)-变量
    字符函数和字符串函数(1)
    Thread的使用、线程的几个重要操作和状态【JavaEE初阶】
    3-运行第一个docker image-hello world
    mysql面试题8:MySQL的日志有哪些?MySQL的bin log、redo log、undo log区别和联系
  • 原文地址:https://blog.csdn.net/GY_U_YG/article/details/125472794