• 手写bind源码


    • 改变函数this指向的三个方法:call   bind  apply

                    三个方法的相同点:

                                  目标函数被调用时,改变this的指向的值

                                  三个方法都是函数的方法,挂在在Function.prototype上

                    不同点:

                                目标函数调用call和apply后,会直接被执行

                                目标函数调用bind后,不会立即执行,而是返回一个新的函数,调用新函数才会执行目标函数

    //自定义一个类似于bind函数的函数,将其挂载到函数Function上面,然后就可以用函数来调用该自定义的函数了
            //给函数扩展一个方法
            Function.prototype.customeBind = function (thisArg,...list){
                let self = this;
                console.log(self)//func
                //返回一个新函数
                return function(...arg2){
                    //改变this的指向
                    self.apply(thisArg,[...list,...arg2])
                }
    
            }
            function func(...arg){
                console.log(this);
                console.log(arg);
            }
            func.prototype.miaov = function (){
                console.log(123)
            }
            let newFunc = func.bind({a:1},1,2,3,4);
            //自定义bind函数
            let newFunc2 = func.customeBind({a:1},1,2,3,4)
            newFunc(5,6,7,8)
            newFunc2(5,6,7,8);
    • 目标函数的实现

    1.目标函数调用后返回新函数

    2.调用新函数,也就是调用目标函数this为传入bind的第一个参数

    3.把新函数当作构造函数,是可以找到目标函数的原型,所以新函数继承目标函数的原型

    4.新函数当作构造函数后,目标函数this指向为原型对象

    // 注意
      /*
    目标函数:调用bind的函数,func.bind func就称之为是目标函数
    新函数:bind返回的函数,
      */
      /*
    1.返回的函数作为构造函数,新函数要继承目标函数的原型
    2.一旦把新函数当成构造函数了,目标函数的this应该指向实例对象
      */
    
            //构造函数的问题
             Function.prototype.customeBind = function (thisArg,...list){
                let self = this;
                console.log(self)//func
    
               //自己实现的bind函数,如果把返回的新函数当成构造函数,此时会遇到问题,就是找不到目标函数原型上的方法,解决:放新函数继承目标函数的原型
               let Bound =  function(...arg2){
                    //改变this的指向
                    // self.apply(thisArg,[...list,...arg2])
                    //如果这个函数作为了构造函数,那么目标函数的this,应该执行的是实例对象
                    //如果这个不是作为构造函数,目标函数中的this还指向thisArg
                    let thisArgSelf = this instanceof Bound ? this : thisArg;
                    self.apply(thisArgSelf,[...list,...arg2])
                    
                }
                //原型继承
                // Bound.prototype = self.prototype;
                //Object.create用来创建以某一个对象作为原型的对象的
                Bound.prototype = Object.create(self.prototype)//创建一个新的对象,该新对象是以self.prototype作为原型创建出来的
                Bound.prototype.constructor = self
    
                //返回一个新函数
                return Bound
    
            }
            function func(...arg){
                console.log(this);
                console.log(arg);
            }
            func.prototype.miaov = function (){
                console.log(123)
            }
            let newFunc = func.bind({a:1},1,2,3,4);
            //自定义bind函数
            let newFunc2 = func.customeBind({a:1},1,2,3,4)
            //构造函数
            let f1 =new newFunc(5,6,7,8)
            console.log(f1.miaov)
            let f2 =new newFunc2(5,6,7,8);
            console.log(f2.miaov)//undefined,因为f2是newFunc2的一个返回值创建出来的,这个返回值就是customeBind函数里面的匿名韩式创建出来的,而这个匿名函数于customeBind没有关联
  • 相关阅读:
    docker 日常使用笔记
    docker swarm:启动多个 overlay网络出现 could not find an available IP while allocating VIP问题
    docker 容器启动失败:Could not attach to network
    fabric : orderer启动失败
    git 代码迁移
    Docker 远程访问
    Struts2标签
    BS与CS的联系与区别
    Java的引用和C++的指针de区别
    抽象类和接口的区别
  • 原文地址:https://www.cnblogs.com/psxiao/p/11469427.html
Copyright © 2020-2023  润新知