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 相关文章推荐
HTA版JSMin(省略修饰语若干)基于javascript语言编写
Dec 24 Javascript
namespace.js Javascript的命名空间库
Oct 11 Javascript
js截取小数点后几位的写法
Nov 14 Javascript
使用JQuery快速实现Tab的AJAX动态载入(实例讲解)
Dec 11 Javascript
创建js对象和js类的方法汇总
Dec 24 Javascript
使用console进行性能测试
Apr 27 Javascript
js实现密码强度检测【附示例】
Mar 30 Javascript
jQuery中$.grep() 过滤函数 数组过滤
Nov 22 Javascript
详解Vue的computed(计算属性)使用实例之TodoList
Aug 07 Javascript
Vue实现导出excel表格功能
Mar 30 Javascript
微信小程序scroll-view实现字幕滚动
Jul 14 Javascript
解决Angularjs异步操作后台请求用$q.all排列先后顺序问题
Nov 29 Javascript
无需 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中调用JAVA
2006/10/09 PHP
杏林同学录(六)
2006/10/09 PHP
ThinkPHP多语言支持与多模板支持概述
2014/08/22 PHP
Thinkphp框架开发移动端接口(2)
2016/08/18 PHP
如何利用预加载优化Laravel Model查询详解
2017/08/11 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
2020/04/04 PHP
List all the Databases on a SQL Server
2007/06/21 Javascript
JavaScript高级程序设计(第3版)学习笔记7 js函数(上)
2012/10/11 Javascript
jquery获得keycode的示例代码
2013/12/30 Javascript
javascript获取checkbox复选框获取选中的选项
2014/08/12 Javascript
js获取域名的方法
2015/01/27 Javascript
jQuery+AJAX实现无刷新下拉加载更多
2015/07/03 Javascript
JS检测移动端横竖屏的代码
2016/05/30 Javascript
Angular.js实现注册系统的实例详解
2016/12/18 Javascript
js Canvas实现的日历时钟案例分享
2016/12/25 Javascript
javaScript中封装的各种写法示例(推荐)
2017/07/03 Javascript
微信小程序 获取javascript 里的数据
2017/08/17 Javascript
ligerUI---ListBox(列表框可移动的实例)
2017/11/28 Javascript
实战node静态文件服务器的示例代码
2018/03/08 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
JQuery常用选择器功能与用法实例分析
2019/12/23 jQuery
详解如何修改 node_modules 里的文件
2020/05/22 Javascript
[10:21]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster 选手采访
2021/03/11 DOTA
Python实现的求解最大公约数算法示例
2018/05/03 Python
python随机数分布random测试
2018/08/27 Python
一步步教你用python的scrapy编写一个爬虫
2019/04/17 Python
Python实现AI换脸功能
2020/04/10 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
2020/06/28 Python
Python 图片处理库exifread详解
2021/02/25 Python
一款纯css3实现的圆形旋转分享按钮旋转角度可自己调整
2014/09/02 HTML / CSS
党员国庆节演讲稿范文2014
2014/09/21 职场文书
场地使用证明模板
2014/10/25 职场文书
2014年大班保育员工作总结
2014/12/02 职场文书
2015中学教学工作总结
2015/07/22 职场文书
初中数学教学反思范文
2016/02/17 职场文书
浅谈golang package中init方法的多处定义及运行顺序问题
2021/05/06 Golang