(推荐)js apply()、call()和bind()的区别,手写Bind的实现原理

手写bind()

描述:

bind()和apply还有call都可以改变关键词this的作用域,它们的用法有所不同,各有千秋,以下是对三个函数的描述和使用例子:

  • apply:func.apply(obj,[arg1,arg2,...]) 把函数func内部的this作用域指向obj,然后把传给func的参数分别放到数组中传给func
    (推荐)js apply()、call()和bind()的区别,手写Bind的实现原理

  • call:func.call(obj,arg1,arg2,...) 与apply类似,不过传参的方式是一个一个传,不用放在数组里边
    (推荐)js apply()、call()和bind()的区别,手写Bind的实现原理

  • bind:func.bind(obj,arg1,arg2,...)(other-arg); 与call和apply不同的是,bind()可以预定义参数,arg1和arg2为预定义的参数,other-arg为其他参数,这么做的好处在于,我们可以用先用一个变量var vary = func.bind(obj,arg1,arg2,...),然后再使用vary(other-arg)来传入其他参数,如此一来,就相当于给函数预先传入了一些相对不变参数,一些需要变化的参数再另外传入,这是apply和call都做不到的。
    bind的用法举例及其效果
    (推荐)js apply()、call()和bind()的区别,手写Bind的实现原理
    (推荐)js apply()、call()和bind()的区别,手写Bind的实现原理

手写bind代码部分:

    // 定义在Function.prototype上,好让使用Function构造器创建新函数的时候都自带bind()方法
    Function.prototype.bind=function(obj,arg){
    // 获取从第二个参数起也就是除了obj之外的其余参数
    var arg=Array.prototype.slice.call(arguments,1);
    // 把this作用域赋给context,因为关键词this的作用域在不同的地方不一样
    var context=this;
    // 定义一个函数,使之可以拼接原bind函数传入的参数,即bind(obj,args1)(args2) == bind(obj,args1,args2)
    // 这里默认让newArg为一个对象,不然会报错
    var bound=function(newArg={}){
    arg=arg.concat(Array.prototype.slice.call(newArg));
    return context.apply(obj,arg);
    }
    // 接下来就是创建一个新函数,使它的prototype(原型对象)等于Function的prototype,然后再把要return的函数bound的prototype指向F这个构造函数,
    // 就把bind()方法放到Function.prototype中去了
    var F=function(){}
    F.prototype=context.prototype;
    bound.prototype=new F();
    return bound;
    }

附一张原型链图方便大家理解:

(推荐)js apply()、call()和bind()的区别,手写Bind的实现原理

参考文章(对原型链的理解):

https://www.jianshu.com/p/423f72d502c2 还不懂原型链的建议看看

(推荐)js apply()、call()和bind()的区别,手写Bind的实现原理

上一篇:命令行下打开appium server


下一篇:如何快速的将手机存储(内存)/SD卡/TF卡打满?