JS中使用apply、bind实现为函数或者类传入动态个数的参数


Posted in Javascript onApril 26, 2016

为纪念10年没写blog,第一篇博文就以这样一个有趣的窍门开始吧 -___-

在ES5中,当我们调用一个函数时,如果要传入的参数是根据其他函数或条件判断生成的,也就是说不确定会传入多少个参数时,在不改变原函数的情况下该如何办呢?

(当然了,能避免此文所述情况发生就尽量避免,比如将参数改为object或array等等)

JS中使用apply、bind实现为函数或者类传入动态个数的参数

大部分人可能知道用apply能完美解决这个问题:

JS中使用apply、bind实现为函数或者类传入动态个数的参数

apply与call一样会将第一个参数作为函数的调用对象,即改写了调用函数内的this指针为第一个参数,如果不是对象的方法,可以不考虑this,传入一个null即可。

而不同之处在于后面的参数,apply将所有要传入调用函数的参数放在一个数组中,call是与原函数一样依次追加进去。

JS中使用apply、bind实现为函数或者类传入动态个数的参数

既然是数组那就可控了,根据其他函数或逻辑判断来生成数组,可达到传入动态个数参数的目的。

但是我遇到一个头疼的问题,要在用new创建对象时传入动态个参数,几年才遇到一次的问题:

JS中使用apply、bind实现为函数或者类传入动态个数的参数

如果是用ES6,有了rest参数,上述问题全都不是问题。注意,数组args前面加三个点并不是语法错误,而是ES6提供的rest参数写法,你可以理解为将...args替换为args数组去掉方括号后的字符。

JS中使用apply、bind实现为函数或者类传入动态个数的参数

但ES5里真的就没有办法实现了吗?毕竟ES6大部分都是语法糖,可以用babel一类的工具编译为ES5,带着疑问,我们就用babel编译一下看看得到什么:

JS中使用apply、bind实现为函数或者类传入动态个数的参数

看到最后一行惊呆了,别害怕,让我们分析一下这句代码。首先肢解一下,分三步来看:

JS中使用apply、bind实现为函数或者类传入动态个数的参数

1. 毫无疑问,用concat将null与我们的参数连接为一个数组,作为apply第二个参数,即得到[null, 1, 2, 3];

2. 让我们运算一下apply,第一个参数Foo会取代Function来调用原生的bind方法,第二个参数数组的内容将作为bind的参数传入,即得到Foo.bind(null, 1, 2, 3);

3. bind方法第一个参数与apply、call类似,修改this指针,而后面的参数可以为函数植入默认的前置参数值(preset leading argument),也就是说当bind执行完后在第一组小括号内我们得到一个已经注入了三个参数值的Foo类,暂且叫FooWithArgs;

最终,当我们 new FooWithArgs(); 时,就不用传入任何参数了。等同于 new Foo(1, 2, 3);

Javascript 相关文章推荐
js中document.getElementByid、document.all和document.layers区分介绍
Dec 08 Javascript
深入领悟JavaScript中的面向对象
Nov 18 Javascript
基于Jquery实现表单验证
Jul 20 Javascript
JavaScript实现自动弹出窗口并自动关闭窗口的方法
Aug 06 Javascript
浅谈Angularjs link和compile的使用区别
Oct 21 Javascript
微信开发 消息推送实现代码
Oct 21 Javascript
浅述Javascript的外部对象
Dec 07 Javascript
AngularJS中的拦截器实例详解
Apr 07 Javascript
详解Vue组件实现tips的总结
Nov 01 Javascript
JS实现快递单打印功能【推荐】
Jun 21 Javascript
详解vue 数组和对象渲染问题
Sep 21 Javascript
jQuery实现简单评论功能
Aug 19 jQuery
无需 Flash 使用 jQuery 复制文字到剪贴板
Apr 26 #Javascript
JavaScript事件处理的方式(三种)
Apr 26 #Javascript
学习AngularJs:Directive指令用法(完整版)
Apr 26 #Javascript
jQuery siblings()用法实例详解
Apr 26 #Javascript
JQuery插件Marquee.js实现无缝滚动效果
Apr 26 #Javascript
Angular.js回顾ng-app和ng-model使用技巧
Apr 26 #Javascript
Bootstrap每天必学之工具提示(Tooltip)插件
Apr 26 #Javascript
You might like
PHP file_exists问题杂谈
2012/05/07 PHP
在smarty中调用php内置函数的方法
2013/02/07 PHP
PHP实现一个轻量级容器的方法
2019/01/28 PHP
javascript实现的listview效果
2007/04/28 Javascript
纯JAVASCRIPT图表动画插件Highcharts Examples
2011/04/16 Javascript
javascript权威指南 学习笔记之null和undefined
2011/09/25 Javascript
浅谈js中变量初始化
2015/02/03 Javascript
浅谈jQuery绑定事件会叠加的解决方法和心得总结
2016/10/26 Javascript
jquery表单验证实例仿Toast提示效果
2017/03/03 Javascript
ES6中参数的默认值语法介绍
2017/05/03 Javascript
JavaScrpt判断一个数是否是质数的实例代码
2017/06/11 Javascript
vue.js如何更改默认端口号8080为指定端口的方法
2017/07/14 Javascript
微信小程序实现下载进度条的方法
2017/12/08 Javascript
详解js模板引擎art template数组渲染的方法
2018/10/09 Javascript
深入浅析Node.js 事件循环、定时器和process.nextTick()
2018/10/22 Javascript
微信小程序自定义弹窗wcPop插件
2018/11/19 Javascript
小程序scroll-view安卓机隐藏横向滚动条的实现详解
2019/05/16 Javascript
JS实现图片切换特效
2019/12/23 Javascript
vue路由权限校验功能的实现代码
2020/06/07 Javascript
Python和C/C++交互的几种方法总结
2017/05/11 Python
Java编程迭代地删除文件夹及其下的所有文件实例
2018/02/10 Python
Python3匿名函数lambda介绍与使用示例
2019/05/18 Python
分析运行中的 Python 进程详细解析
2019/06/22 Python
Python 变量的创建过程详解
2019/09/02 Python
python flask中动态URL规则详解
2019/11/22 Python
Python数据可视化:饼状图的实例讲解
2019/12/07 Python
使用matlab 判断两个矩阵是否相等的实例
2020/05/11 Python
详解css3 object-fit属性
2018/07/27 HTML / CSS
解决HTML5中的audio在手机端和微信端的不能自动播放问题
2019/11/04 HTML / CSS
实习护士自我鉴定
2013/10/13 职场文书
经销商培训邀请函
2014/01/21 职场文书
学雷锋月活动总结
2014/04/25 职场文书
环境卫生整治简报
2015/07/20 职场文书
竞聘开场白方式有哪些?
2019/08/28 职场文书
mybatis中sql语句CDATA标签的用法说明
2021/06/30 Java/Android
Windows Server 2016 配置 IIS 的详细步骤
2022/04/28 Servers