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 相关文章推荐
基于jquery的地址栏射击游戏代码
Mar 10 Javascript
js怎么覆盖原有方法实现重写
Sep 04 Javascript
jQuery中fadeOut()方法用法实例
Dec 24 Javascript
js实现模拟银行卡账号输入显示效果
Nov 18 Javascript
下雪了 javascript实现雪花飞舞
Aug 02 Javascript
值得分享的Bootstrap Table使用教程
Nov 23 Javascript
js技巧之十几行的代码实现vue.watch代码
Jun 09 Javascript
微信小程序map组件结合高德地图API实现wx.chooseLocation功能示例
Jan 23 Javascript
jquery操作checkbox的常用方法总结【附测试源码下载】
Jun 10 jQuery
vue实现图片懒加载的方法分析
Feb 05 Javascript
解决antd日期选择组件,添加value就无法点击下一年和下一月问题
Oct 29 Javascript
vue报错function () { [native code] },无法出现我们想要的内容 Unknown custom element
Apr 11 Vue.js
无需 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购物车实现代码
2011/10/10 PHP
twig里使用js变量的方法
2016/02/05 PHP
php reset() 函数指针指向数组中的第一个元素并输出实例代码
2016/11/21 PHP
利用PHP_XLSXWriter代替PHPExcel的方法示例
2017/07/16 PHP
laravel自定义分页的实现案例offset()和limit()
2019/10/15 PHP
jquery等宽输出文字插件使用介绍
2013/09/18 Javascript
js之ActiveX控件使用说明 new ActiveXObject()
2014/03/03 Javascript
js控制href内容的连接内容的变化示例
2014/04/30 Javascript
JS使用oumousemove和oumouseout动态改变图片显示的方法
2015/03/31 Javascript
浅谈JavaScript异常处理语句
2015/06/26 Javascript
html+js实现简单的计算器代码(加减乘除)
2016/07/12 Javascript
Angularjs 双向绑定时字符串的转换成数字类型的问题
2017/06/12 Javascript
Angular 4根据组件名称动态创建出组件的方法教程
2017/11/01 Javascript
anime.js 实现带有描边动画效果的复选框(推荐)
2017/12/24 Javascript
微信小程序实现图片预览功能
2018/01/31 Javascript
JS装饰器函数用法总结
2018/04/21 Javascript
Vue实现简单计算器案例
2020/02/25 Javascript
在vue中created、mounted等方法使用小结
2020/07/21 Javascript
在vue中使用Echarts画曲线图的示例
2020/10/03 Javascript
JavaScript实现简易计算器小功能
2020/10/22 Javascript
[02:38]2018年度DOTA2最佳劣单位选手-完美盛典
2018/12/17 DOTA
Python中的lstrip()方法使用简介
2015/05/19 Python
Python抓取框架Scrapy爬虫入门:页面提取
2017/12/01 Python
详解Python基础random模块随机数的生成
2019/03/23 Python
Keras自定义实现带masking的meanpooling层方式
2020/06/16 Python
python多线程和多进程关系详解
2020/12/14 Python
canvas实现滑动验证的实现示例
2020/08/11 HTML / CSS
French Connection官网:女装、男装及家居用品
2019/03/18 全球购物
下面这个程序执行后会有什么错误或者效果
2014/11/03 面试题
咖啡厅创业计划书范本
2014/01/22 职场文书
2016学习雷锋精神活动倡议书
2015/04/27 职场文书
教师教育心得体会
2016/01/19 职场文书
2016年世界艾滋病日宣传活动总结
2016/04/01 职场文书
Redis基于Bitmap实现用户签到功能
2021/06/20 Redis
分析Java中Map的遍历性能问题
2021/06/26 Java/Android
解决Windows Server2012 R2 无法安装 .NET Framework 3.5
2022/04/29 Servers