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 相关文章推荐
Prototype Function对象 学习
Jul 12 Javascript
Mootools 1.2教程 函数
Sep 15 Javascript
Javascript浅谈之this
Dec 17 Javascript
javascript去除字符串左右两端的空格
Feb 05 Javascript
JS控制按钮10秒钟后可用的方法
Dec 22 Javascript
原生JS改变透明度实现轮播效果
Mar 24 Javascript
javaScript 连接打印机,打印小票的实例
Dec 29 Javascript
cropper js基于vue的图片裁剪上传功能的实现代码
Mar 01 Javascript
vue和webpack打包项目相对路径修改的方法
Jun 15 Javascript
详解vue中router-link标签所必备了解的属性
Apr 15 Javascript
vue使用lodop打印控件实现浏览器兼容打印的方法
Feb 07 Vue.js
JS实现简单九宫格抽奖
Jun 28 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 5.3 下载时 VC9、VC6、Thread Safe、Non Thread Safe的区别分析
2011/03/28 PHP
PHP发明人谈MVC和网站设计架构 貌似他不支持php用mvc
2011/06/04 PHP
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
PHP curl 获取响应的状态码的方法
2014/01/13 PHP
phpExcel中文帮助手册之常用功能指南
2014/08/18 PHP
浅谈thinkphp的实例化模型
2015/01/04 PHP
PHP SESSION的增加、删除、修改、查看操作
2015/03/20 PHP
php实现将任意进制数转换成10进制的方法
2015/04/17 PHP
YiiFramework入门知识点总结(图文教程)
2015/12/28 PHP
dojo学习第一天 Tab选项卡 实现
2011/08/28 Javascript
js动态调用css属性的小规律及实例说明
2013/12/28 Javascript
从零学jquery之如何使用回调函数
2014/05/16 Javascript
jQuery对象的selector属性用法实例
2014/12/27 Javascript
javascript数组去重方法汇总
2015/04/23 Javascript
jquery带翻页动画的电子杂志代码分享
2015/08/21 Javascript
图解Sublime Text3使用技巧
2015/12/21 Javascript
JavaScript实现简单Tip提示框效果
2016/04/20 Javascript
js时间查询插件使用详解
2017/04/07 Javascript
详解angularjs利用ui-route异步加载组件
2017/05/21 Javascript
JS实现json的序列化和反序列化功能示例
2017/06/13 Javascript
Bootstrap treeview实现动态加载数据并添加快捷搜索功能
2018/01/07 Javascript
react 移动端实现列表左滑删除的示例代码
2019/07/04 Javascript
Vue 路由间跳转和新开窗口的方式(query、params)
2019/12/25 Javascript
详解vue 组件的实现原理
2020/11/12 Javascript
Vue项目如何引入bootstrap、elementUI、echarts
2020/11/26 Vue.js
学习Python3 Dlib19.7进行人脸面部识别
2018/01/24 Python
python中实现控制小数点位数的方法
2019/01/24 Python
使用python读取.text文件特定行的数据方法
2019/01/28 Python
twilio python自动拨打电话,播放自定义mp3音频的方法
2019/08/08 Python
python 基于卡方值分箱算法的实现示例
2020/07/17 Python
pandas按照列的值排序(某一列或者多列)
2020/12/13 Python
python接口自动化框架实战
2020/12/23 Python
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
社区文艺活动方案
2014/08/19 职场文书
幼儿园教师节活动总结
2015/03/23 职场文书
2016年公司新年寄语
2015/08/17 职场文书