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在firefox中关闭窗口再打开后iframe中js函数访问不到的问题
Nov 06 Javascript
JavaScript 学习技巧
Feb 17 Javascript
AJAX 网页保留浏览器前进后退等功能
Feb 12 Javascript
使用Jquery打造最佳用户体验的登录页面的实现代码
Jul 08 Javascript
Web开发之JavaScript
Mar 29 Javascript
父节点获取子节点的字符串示例代码
Feb 26 Javascript
jquery.validate.js插件使用经验记录
Jul 02 Javascript
省市联动效果的简单实现代码(推荐)
Jun 06 Javascript
js字符串操作总结(必看篇)
Nov 22 Javascript
12306 刷票脚本及稳固刷票脚本(防挂)
Jan 04 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
Feb 05 Javascript
Vue组件全局注册实现警告框的实例详解
Jun 11 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
77A一级收信机修理记
2021/03/02 无线电
PHP文本数据库的搜索方法
2006/10/09 PHP
解析smarty模板中类似for的功能实现
2013/06/18 PHP
在WordPress中使用PHP脚本来判断访客来自什么国家
2015/12/10 PHP
php微信公众平台开发(三)订阅事件处理
2016/12/06 PHP
Laravel中服务提供者和门面模式的入门介绍
2017/11/06 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
用js实现预览待上传的本地图片
2007/03/15 Javascript
JavaScript 5 新增 Array 方法实现介绍
2012/02/06 Javascript
IScroll5 中文API参数说明和调用方法
2016/05/21 Javascript
JS 滚动事件window.onscroll与position:fixed写兼容IE6的回到顶部组件
2016/10/10 Javascript
微信小程序教程之本地图片上传(leancloud)实例详解
2016/11/16 Javascript
vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
2017/03/06 Javascript
Angular4自制一个市县二级联动组件示例
2017/11/21 Javascript
JS滚轮控制图片缩放大小和拖动的实例代码
2018/11/20 Javascript
详解vue beforeRouteEnter 异步获取数据给实例问题
2019/08/09 Javascript
layui使用templet格式化表格数据的方法
2019/09/16 Javascript
详解React 元素渲染
2020/07/07 Javascript
[01:02:05]LGD vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
全面理解Python中self的用法
2016/06/04 Python
介绍一款python类型检查工具pyright(推荐)
2019/07/03 Python
pytorch 更改预训练模型网络结构的方法
2019/08/19 Python
python实现ip地址的包含关系判断
2020/02/07 Python
PyCharm 无法 import pandas 程序卡住的解决方式
2020/03/09 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
python使用Thread的setDaemon启动后台线程教程
2020/04/25 Python
python 如何停止一个死循环的线程
2020/11/24 Python
css3 box-shadow阴影(外阴影与外发光)图示讲解
2017/08/11 HTML / CSS
HTML5边玩边学(2)基础绘图实现方法
2010/09/21 HTML / CSS
澳大利亚领先的美容护肤品零售商之一:SkincareStore
2018/01/22 全球购物
Wedgwood美国官网:英国骨瓷,精美礼品及家居装饰
2018/02/17 全球购物
Java语言程序设计测试题改错题部分
2014/07/22 面试题
大学生的自我鉴定范文
2014/01/21 职场文书
装配车间主任岗位职责
2015/04/08 职场文书
为什么在foreach循环中JAVA集合不能添加或删除元素
2021/06/11 Java/Android
Java中使用Filter过滤器的方法
2021/06/28 Java/Android