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 相关文章推荐
Extjs学习笔记之三 extjs form更多的表单项
Jan 07 Javascript
jQuery之自动完成组件的深入解析
Jun 19 Javascript
jquery ajax post提交数据乱码
Nov 05 Javascript
Javascript和Java获取各种form表单信息的简单实例
Feb 14 Javascript
node.js中的dns.getServers方法使用说明
Dec 08 Javascript
jQuery幻灯片特效代码分享--鼠标滑过按钮时切换(2)
Nov 18 Javascript
学习JavaScript设计模式(单例模式)
Nov 26 Javascript
jQuery实现百叶窗焦点图动画效果代码分享(附源码下载)
Mar 14 Javascript
仅9张思维导图帮你轻松学习Javascript 就这么简单
Jun 01 Javascript
bootstrap模态框跳转到当前模板页面 框消失了而背景存在问题的解决方法
Nov 30 Javascript
jQuery实现鼠标响应式透明度渐变动画效果示例
Feb 13 jQuery
vue计算属性无法监听到数组内部变化的解决方案
Nov 06 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
ThinkPHP中自定义错误页面和提示页面实例
2014/11/22 PHP
php查找指定目录下指定大小文件的方法
2014/11/28 PHP
PHP常用处理静态操作类
2015/04/03 PHP
php实现xml与json之间的相互转换功能实例
2016/07/07 PHP
AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
2010/03/04 Javascript
javascript循环变量注册dom事件 之强大的闭包
2010/09/08 Javascript
JavaScript中的作用域链和闭包
2012/06/30 Javascript
javascript判断chrome浏览器的方法
2014/03/26 Javascript
jQuery防止click双击多次提交及传递动态函数或多参数
2014/04/02 Javascript
JavaScript作用域链示例分享
2014/05/27 Javascript
Web表单提交之disabled问题js解决方法
2015/01/13 Javascript
Javascript实现的SHA-256加密算法完整实例
2016/02/02 Javascript
JQuery的常用选择器、过滤器、方法全面介绍
2016/05/25 Javascript
jQuery筛选数组之grep、each、inArray、map的用法及遍历json对象
2016/06/20 Javascript
jQuery的图片轮播插件PgwSlideshow使用详解
2016/08/11 Javascript
Bootstrap面板使用方法
2017/01/16 Javascript
原生JS改变透明度实现轮播效果
2017/03/24 Javascript
Vue-Cli项目优化操作的实现
2019/10/27 Javascript
BootstrapValidator验证用户名已存在(ajax)
2019/11/08 Javascript
python线程、进程和协程详解
2016/07/19 Python
python实现读取并显示图片的两种方法
2017/01/13 Python
Python抓取框架Scrapy爬虫入门:页面提取
2017/12/01 Python
pytorch ImageFolder的覆写实例
2020/02/20 Python
Python使用pickle进行序列化和反序列化的示例代码
2020/09/22 Python
基于HTML5新特性Mutation Observer实现编辑器的撤销和回退操作
2016/01/11 HTML / CSS
加拿大最大的钻石商店:Peoples Jewellers
2018/01/01 全球购物
瑞典最大的儿童用品网上商店:pinkorblue.se
2021/03/09 全球购物
课改先进个人汇报材料
2014/01/26 职场文书
幼儿园校车司机的岗位职责
2014/01/30 职场文书
80后职场人的职业生涯规划
2014/03/08 职场文书
就业协议书怎么填
2014/04/11 职场文书
百日安全生产活动总结
2014/07/05 职场文书
2015大学生求职信范文
2015/03/20 职场文书
医者仁心观后感
2015/06/17 职场文书
解决Python保存文件名太长OSError: [Errno 36] File name too long
2022/05/11 Python
MySQL存储过程及语法详解
2022/08/05 MySQL