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 相关文章推荐
Prototype1.6 JS 官方下载地址
Nov 30 Javascript
JS弹出对话框返回值代码(asp.net后台)
Dec 28 Javascript
密码强度检测效果实现原理与代码
Jan 04 Javascript
JQuery.Ajax之错误调试帮助信息介绍
Jul 04 Javascript
instanceof和typeof运算符的区别详解
Jan 06 Javascript
AngularJs concepts详解及示例代码
Sep 01 Javascript
用jquery获取自定义的标签属性的值简单实例
Sep 17 Javascript
jQuery 获取select选中值及清除选中状态
Dec 13 Javascript
vue2.0 循环遍历加载不同图片的方法
Mar 06 Javascript
微信小程序实现留言板(Storage)
Nov 02 Javascript
详解关于微信setData回调函数中的坑
Feb 18 Javascript
Vue+Koa2+mongoose写一个像素绘板的实现方法
Sep 10 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 has encountered an Access Violation
2007/01/15 PHP
PHP 中使用explode()函数切割字符串为数组的示例
2017/05/06 PHP
JavaScript 仿关机效果的图片层
2008/12/26 Javascript
asp.net下使用jquery 的ajax+WebService+json 实现无刷新取后台值的实现代码
2010/09/19 Javascript
再说AutoComplete自动补全之实现原理
2011/11/05 Javascript
JQuery 图片的展开和伸缩实例讲解
2013/04/18 Javascript
javascript 操作符(~、&、|、^、)使用案例
2014/12/31 Javascript
jQuery trigger()方法用法介绍
2015/01/13 Javascript
javascript字符串循环匹配实例分析
2015/07/17 Javascript
JavaScript时间操作之年月日星期级联操作
2016/01/15 Javascript
浅谈JavaScript中小数和大整数的精度丢失
2016/05/31 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
2016/06/12 Javascript
Vue.js -- 过滤器使用总结
2017/02/18 Javascript
微信小程序 支付功能实现PHP实例详解
2017/05/12 Javascript
jQuery实现弹窗下底部页面禁止滑动效果
2017/12/19 jQuery
Layui 设置select下拉框自动选中某项的方法
2018/08/14 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
JS中getElementsByClassName与classList兼容性问题解决方案分析
2019/08/07 Javascript
区分vue-router的hash和history模式
2020/10/03 Javascript
[36:05]DOTA2亚洲邀请赛 3.31 小组赛 A组 Liquid vs Optic
2018/04/01 DOTA
Python判断文本中消息重复次数的方法
2016/04/27 Python
python 编码规范整理
2018/05/05 Python
基于python3抓取pinpoint应用信息入库
2020/01/08 Python
python数据处理——对pandas进行数据变频或插值实例
2020/04/22 Python
详解Html5中video标签那些属性和方法
2019/07/01 HTML / CSS
阿迪达斯意大利在线商店:adidas意大利
2016/09/19 全球购物
复古风格的女装和装饰品:ModCloth
2017/12/29 全球购物
HEMA英国:荷兰原创设计
2018/08/28 全球购物
到底Java是如何传递参数的?是by value或by reference?
2012/07/13 面试题
大学生村官典型材料
2014/01/12 职场文书
妇女儿童发展规划实施方案
2014/03/16 职场文书
旅游文化节策划方案
2014/06/06 职场文书
皇城相府导游词
2015/02/06 职场文书
用golang如何替换某个文件中的字符串
2021/04/25 Golang
JS ES6异步解决方案
2021/04/29 Javascript
Nginx内网单机反向代理的实现
2021/11/07 Servers