背景:

小明想要用数组的形式为 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. Visual Studio 2015/2017 与ASP.NET CORE 联合创建具有SPA模式的Angular2模板

    虽然注册博客园很久,但是一直没有什么可写的,真心感觉好尴尬了,这次终于找到了一点可以写,有点小兴奋和小害羞呢. 进入主题,前端SPA模式越来越受到欢迎,Core 也开始被很多企业提上日程,但是因为这个 ...

  2. C++数据

    const :常量 ~x == -++x == -(x+1)   二进制数,1变为0,0变为1 ^                               相同为0,不同为1 &      ...

  3. cudaMemcpy与cudaMemcpyAsync的区别

    转载请注明来源:http://www.cnblogs.com/shrimp-can/p/5231857.html 简单可以理解为:cudaMemcpy是同步的,而cudaMemcpyAsync是异步的 ...

  4. Android中查看布局文件中的控件(view,id)在哪里被调用(使用)

    在阅读别人的代码时通常是很痛苦的,有时很想要看一看布局中的控件在哪里被调用了,为之很苦恼 在这里提供一种方法.   复制要查看的控件ID,到R文件中搜索到该ID,   接下来就好办的了,选中ID按下C ...

  5. [cookie篇]从cookie-parser中间件说起

    当我们在写web的时候,难免会要使用到cookie,由于node.js有了express这个web框架,我们就可以方便地去建站.在使用express时,经常会使用到cookie-parser这个插件. ...

  6. 基于HBase的手机数据备份系统 .

    基于HBase实现的手机数据备份系统,实现了手机关键信息的备份,如短信.联系人等. 包括服务器端(Server)和客户端(Client) Server运行环境:Hadoop+HBase+Tomcat ...

  7. ajax ----进度条的原理

    一.进度条的原理 新知识点:Html5中FormData,xmlHttpRequest中的upload属性,progress事件监控 xmlHttpRequest中的upload属性,实现: < ...

  8. css3+js 实现砸金蛋效果

    最近闲来无事,在网上看到有人写了个砸金蛋的效果,他是没有用到css3的,当时我就感觉没什么动态效果 感觉体验不是很好,所有我就想用css3来改下,于是也来试着写写. 本来想弄个视频给你们看看效果的,但 ...

  9. 1094:零起点学算法01——第一个程序Hello World!

    Description 题目很简单 输出"Hello World!"(不含引号),并换行. Input 没有输入 Output 输出"Hello World!" ...

  10. ML(4): NavieBayes在R中的应用

    朴素贝叶斯方法是一种使用先验概率去计算后验概率的方法, 具体见上一节. 算法包:e1071 函数:navieBayes(formule,data,laplace=0,...,subset,na.act ...