码迷,mamicode.com
首页 > 其他好文 > 详细

实现bind的全程思路

时间:2020-04-26 18:47:34      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:eof   查找   prot   并且   new   this指针   行修改   nts   array   

 <script>
    //  分析:  相比于call和apply,bind的返回的是一个函数,并且这个函数完成的任务与apply相同。
    //这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
    //另外由于返回的是一个函数,要考虑这个返回函数作为构造函数被new时的this指针变化,并且保留原型的属性
    Function.prototype.myBind = function(thisArg , ...args){// ...自定义名 代表剩余参数
        let self = this   //为了区分两种this的上下文,先将指向调用者的this保存在self中,
        let fn = function(){       //把fn当作返回函数去制造
          self.apply(this instanceof self ? this : thisArg , args.concat(Array.prototype.slice.call(arguments)))//借用数组原型上的slice,复制一份
            //这个新函数的任务,是将this指向第一个参数,其他参数作为新函数的参数,并且还得接受其他参数得传入(这个新函数要模仿调用者)
            //为了区分fn被new时和正常执行得不同,这里需要用instanceof加一层判断

            // 1. fn函数被当作构造函数,被new运算
            //那么fn中的this指向new出来的实例,也就是说这个新对象是调用者原型的一个实例(this.__proto__ === self.prototype)
            //instanceof 判断成立 
            //根据原型链原理,优先调用自己的属性,再去原型链上查找。为了不丢失实例自身的属性,那么这个apply的第一个参数就只能是new出来的实例,也就是被new时的this
            
            // 2. fn被正常调用
            //默认调用者不在原型链上,也就不需要考虑原型链的要求。直接使用apply将this指向bind的第一个参数,将其他的参数作为新函数的实参。
            //这里考虑到fn函数也需要接收参数(arguments),所以需要将 bind剩余的实参和fn函数接收的参数进行拼接 成为新的参数数组
        }
        // 这时候自己写得fn的prototype指向的是终端原型,因为fn是按调用者的样子造出来的,但是只有调用者的属性,缺少调用者原型上的属性,不够全面。
        //所以将要将fn链接到调用者的原型链上去
        fn.prototype = Object.create(self.prototype)
        //首先我们是想将调用者得prototype直接当作fn得原型,也就是fn.prototype = this.prototype 但是这个写法使得两者指向了同一个地址,会有一定风险。
        //也就是说当我们对fn.prototype进行修改时,会影响到self.prototype得属性。所以不如将self.prototype得一个实例当作fn得原型,就解决了这个问题。
        return fn
    }


    //测试
    const obj = { name: ‘i am cj‘ }
    function foo() {
    console.log(this.name)
    console.log(arguments)
}

foo.myBind(obj, ‘a‘, ‘b‘, ‘c‘)()  

   </script>

 

实现bind的全程思路

标签:eof   查找   prot   并且   new   this指针   行修改   nts   array   

原文地址:https://www.cnblogs.com/620chang/p/12781439.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!