背景:

小明想要用数组的形式为 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

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

.bind.apply() 解决 new 操作符不能用与 apply 或 call 同时使用的更多相关文章

  1. js中bind的用法,及与call和apply的区别

    call和apply的使用和区别不再做阐述,可以参考我的另一篇随笔<JavaScript中call和apply方法的使用>(https://www.cnblogs.com/lcr-smg/ ...

  2. [每天解决一问题系列 - 0001] Javascript apply和 call对比

    相同点: 每个函数都包含这两个原生的方法 他们两个的效果是一样的,用于在特定的作用域下执行函数,本质上是设置函数内this对象的值. 不同点: 传入的参数类型不同 . apply(函数作用域,arra ...

  3. .apply .call方法的区别及使用 .apply第二个参数为数组,.call第二个参数为参数列表, 相同点:第一个参数都为Function函数内部的this对象.

    Function.apply(obj,args)方法能接收两个参数 obj:这个对象将代替Function类里this对象 args:这个是数组,它将作为参数传给Function(args--> ...

  4. 使用call、apply和bind解决js中烦人的this,事件绑定时的this和传参问题

    1.什么是this 在JavaScript中this可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式,this 绑定的对象即函数执行的上下文环境(context). 为了帮助理解,让我 ...

  5. javascript中apply、call和bind的区别及方法详解

    文章目录   apply.call apply.call 区别 apply.call实例 数组之间追加 获取数组中的最大值和最小值 验证是否是数组(前提是toString()方法没有被重写过) 类(伪 ...

  6. JS中的call、apply、bind方法详解

    bind 是返回对应函数,便于稍后调用:apply .call 则是立即调用 . apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(co ...

  7. JS核心系列:浅谈 call apply 与 bind

    在JavaScript 中,call.apply 和 bind 是 Function 对象自带的三个方法,这三个方法的主要作用是改变函数中的 this 指向,从而可以达到`接花移木`的效果.本文将对这 ...

  8. 【优雅代码】深入浅出 妙用Javascript中apply、call、bind

    这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂的知识.我 ...

  9. Javascript中call,apply,bind方法的详解与总结

    在 javascript之 this 关键字详解 文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,thi ...

随机推荐

  1. 2017-3-20 HTML 基础知识

    HTML的定义:HTML是一门编程语言的名字:超文本标记语言(Hyper Text Mark-up Language ),就是超越了文字的范畴,除了文字还可以有图片.视频.音频.动画.特效.表格.链接 ...

  2. 关于Tarjan(3)——离线LCA

    LCA(最近公共祖先),指对于一棵树上任意两个节点往上走最早都能到达的节点. 求LCA有两种方法,一种是倍增,另一种则是Tarjan........ Tarjan巧妙利用并查集的思想: 这里的Tarj ...

  3. system()、exec()、fork()三个与进程有关的函数的比较

    启动新进程(system函数) system()函数可以启动一个新的进程. int system (const char *string ) 这个函数的效果就相当于执行sh –c string. 一般 ...

  4. [译]Selenium Python文档:七、WebDriver API接口

    由于API文档格式不太适合cnblog博客,暂且翻译一部分,且暂未校对 注意:这不是官方文档,官方 API文档在这里. 本章包含Selenium WebDriver的所有接口 推荐import风格 本 ...

  5. KeychainItemWrapper的使用

    KeychinaItemWrapper官方Demo下载地址KeychinaItemWrapper. NSString *identifier = @"xxxxxx";//你要使用的 ...

  6. (转)Nginx启动出错 error while loading shared libraries

    [root@localhost conf]# /usr/local/nginx/sbin/nginx/usr/local/nginx/sbin/nginx: error while loading s ...

  7. 安装vnc远程连接CentOS桌面

    1.查看本机是否有安装vnc(centOS5默认有安装vnc) rpm -q vnc vnc-server 如果显示结果为: package vnc is not installedvnc-serve ...

  8. Android -- onMeasure()源码分析

    1,作为自定义控件最重要的三个方法之一,onMeasure()可以说是我们研究的重点,今天我们更详细的来研究一下View的onMeasure()方法和ViewGroup的onMeasure()方法 2 ...

  9. Docker系列一之基础快速入门企业实战

    1.1什么是LXC LXC为Linux Container的简写.Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚 ...

  10. SPOJ-ANTP [组合数学]

    tags:[组合][预处理]题解:关于方程A+C+B=X的正整数解组数.我们用插板法可知,解的组数=在(X-1)个元素中选择两个元素的方案数故答案为:C(x-1,2)+C(x,2)+C(x+1,2)+ ...