zoukankan      html  css  js  c++  java
  • Fn.bind.apply() 解决 new 操作符不能用与 apply 或 call 同时使用

    背景:

    小明想要用数组的形式为 Cls.func 传入多个参数,他想到了以下的写法:

    var a = new Cls.func.apply(null, [1, 2, 3]);
    

    然而浏览器却报错 Cls.func.apply is not a constructor。
    乍一看是 new 操作符去修饰 Cls.func.apply 了,于是他又这么写:

    var a = (new Cls.func).apply(null, [1, 2, 3]);
    

    浏览器依旧报错。。。好吧,还是好好查一查相关的解决方法吧,还好这是个好时代,没有什么是网上查不出来的。


    思路:

    在网上找到了非常关键的几个解决方案和思路。

    参考链接 http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible

    关键摘抄:

    function newCall(Fn) {
        return new (Function.prototype.bind.apply(Fn, arguments));
        // or even
        // return new (Fn.bind.apply(Fn, arguments));
        // if you know that Fn.bind has not been overwritten
    }
    
    // It can be used as follows:
    var s = newCall(Fn, a, b, c);
    
    // or even directly:
    var a = new (Function.prototype.bind.call(Fn, null, 1, 2, 3));
    
    var a = new (Function.prototype.bind.apply(Fn, [null, 1, 2, 3]));
    

    以上关键就在于 .bind.apply() 或 .bind.call() 这中写法。
    Function.prototype.bind() 等同于 Fn.bind() 会创建一个新的函数,第一个参数为新函数的 this 指向,而后多个参数为绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。

    先分析一下 Function.prototype.bind.call() 这种写法:

    var a = new (Function.prototype.bind.call(Fn, null, 1, 2, 3));
    

    call() 接受多个参数,第一个参数为函数执行的上下文环境,后面的参数会依次传递给前面的 bind 作为参数。
    所以 bind() 接到的参数为 bind(null, 1, 2, 3)。所以上面的那种写法就等同于:

    var a = new ( Fn.bind(null, 1, 2, 3)() );
    

    同理再推导 Function.prototype.bind.apply() 写法:

    var a = new (Function.prototype.bind.apply(Fn, [null, 1, 2, 3]);
    

    call() 接受两个参数,第一个参数为函数执行的上下文环境,第二个参数为数组,数组的每一项会一次作为 bind() 的参数,因此 bind() 接受到的参数也为 bind(null, 1, 2, 3)。因此也等价于:

    var a = new ( Fn.bind(null, 1, 2, 3)() );
    

    解决:

    有了上面的推导,小明这时候就可以轻易的写出自己想要的结果了,同时为了拓展方便,小明决定写一个通用的方法:

    function newApply(Fn, argsAry) {
        argsAry.unshift(null);
        return new (Fn.bind.apply(Fn, argsAry));
    }
    
    // 调用
    newApply(Cls.func, [1, 2, 3]) // well done !!
    

    作者博客:pspgbhu http://www.cnblogs.com/pspgbhu/

    原文链接:http://www.cnblogs.com/pspgbhu/p/6796795.html

    作者GitHubhttps://github.com/pspgbhu

    欢迎转载,但请注明出处,谢谢!

  • 相关阅读:
    js--script和link中的 integrity 属性
    html之aria-hidden="true"
    S-HR之导入模板校验非当天变更限制
    拆分字符串
    S-HR之变动操作,变动原因,变动类型/离职操作,离职原因,离职类型
    mysql数学函数
    html页面引入
    springboot之server属性
    【开发工具】-Idea代码提示忽略大小写
    【个人提升】-怎样获得技术的成长(转)
  • 原文地址:https://www.cnblogs.com/pspgbhu/p/6796795.html
Copyright © 2011-2022 走看看