手写JavaScript中的bind要领

之前已完成过了call,apply和new。本日顺便把bind也完成下。
起首:

  1. bind要领返回的是一个绑定this后的函数,而且该函数并没有实行,须要手动去挪用。(从这一点看bind函数就是一个高阶函数,而且和call,apply要领有区分)。
  2. bind要领能够绑定this,通报参数。注重,这个参数能够分屡次通报。
  3. 假如bind绑定后的函数被new了,那末此时this指向就发作转变。此时的this就是当前函数的实例。
  4. 组织函数上的属性和要领,每一个实例上都有。

ok,上代码~

Function.prototype.mybind = function(context){
    let that = this;
    let args1 = Array.prototype.slice.call(arguments,1);
    let bindFn = function(){
        let args2 = Array.prototype.slice.call(arguments);
        return that.apply(this instanceof bindFn?this:context,args1.concat(args2)); 
    }
    let Fn = function(){};
    Fn.prototype = this.prototype;
    bindFn.prototype = new Fn();
    return bindFn;
}

起首 获取到第一次通报的参数args1,此处要做截取处置惩罚,由于第一个参数是this。接下来声明一个函数bindFn,在该bindFn中获取了第二次传的参数args2,而且返回了that的实行。此处的that就是原函数,实行该原函数绑定原函数this的时刻要注重推断。假如this是组织函数bindFn new出来的实例,那末此处的this一定是该实例自身。反之,则是bind要领通报的this(context)。末了再把两次取得的参数经由过程concat()衔接起来通报进去,如许就完成了前3条。
末了一条:组织函数上的属性和要领,每一个实例上都有。 此处经由过程一个中心函数Fn,来衔接原型链。Fn的prototype即是this的prototype。Fn和this指向同一个原型对象。bindFn的prototype又即是Fn的实例。Fn的实例的__proto__又指向Fn的prototype。即bindFn的prototype指向和this的prototype一样,指向同一个原型对象。至此,就完成了本身的bind要领。
代码写好了, 测试一下吧~

Function.prototype.mybind = function(context){
    let that = this;
    let args1 = Array.prototype.slice.call(arguments,1);
    let bindFn = function(){
        let args2 = Array.prototype.slice.call(arguments);
        return that.apply(this instanceof bindFn?this:context,args1.concat(args2)); 
    }
    let Fn = function(){};
    Fn.prototype = this.prototype;
    bindFn.prototype = new Fn();
    return bindFn;
}

let obj = {
    name:'tiger'
}

function fn(name,age){
    this.say = '汪汪~';
    console.log(this);
    console.log(this.name+'养了一只'+name+','+age+'岁了 ');
}

/** 第一次传参 */
let bindFn = fn.mybind(obj,'🐶');
/** 第二次传参 */
bindFn('10');

/* 组织函数上的属性和要领,每一个实例上都有 */
let instance = new bindFn('20');
bindFn.prototype.type = '哺乳类';
console.log(instance.type);

分别在实行mybind()和实行mybind后函数的时刻,通报了两次参数。而且打印了:

tiger养了一只🐶,10岁了 

能够看到,完成了分两步传参数。
其次,经由过程new 得到了组织函数bindFn的实例instance。在组织函数bindFn上拓展属性type即是’哺乳类’。打印该组织函数的实例instance,能够看到打印出了:哺乳类。
至此,证明了手写的bind要领相符一切预期需求。喜好点个👍,thx~

    原文作者:Funky_Tiger
    原文地址: https://segmentfault.com/a/1190000018460584
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞