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的一行代码轻松实现拖动效果
Dec 28 Javascript
得到form下的所有的input的js代码
Nov 07 Javascript
javascript中实现兼容JAVA的hashCode算法代码分享
Aug 11 Javascript
Javascript设计模式理论与编程实战之简单工厂模式
Nov 03 Javascript
第一次接触神奇的Bootstrap
Oct 14 Javascript
EditPlus中的正则表达式 实战(4)
Dec 15 Javascript
JS中Swiper的使用和轮播图效果
Aug 11 Javascript
简单理解Vue中的nextTick方法
Jan 30 Javascript
webuploader实现上传图片到服务器功能
Aug 16 Javascript
JavaScript实现shuffle数组洗牌操作示例
Jan 03 Javascript
layui table复选框禁止某几条勾选的实例
Sep 20 Javascript
浅探express路由和中间件的实现
Sep 30 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作的文本留言本的例子(六)
2006/10/09 PHP
PHP表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法
2011/08/22 PHP
PHP中strtotime函数使用方法分享
2012/01/10 PHP
采集邮箱的php代码(抓取网页中的邮箱地址)
2012/07/17 PHP
七款最流行的PHP本地服务器分享
2013/02/19 PHP
PHP中一些可以替代正则表达式函数的字符串操作函数
2014/11/17 PHP
php实现二进制和文本相互转换的方法
2015/04/18 PHP
打开超链需要“确认”对话框的方法
2007/03/08 Javascript
javascript高亮效果的二种实现方法
2008/09/14 Javascript
浅析jQuery的链式调用之each函数
2010/12/03 Javascript
document节点对象的获取方式示例介绍
2013/12/24 Javascript
Javascript 按位与赋值运算符 (&=)使用介绍
2014/02/04 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
2015/08/06 Javascript
AngularJS 中的Promise --- $q服务详解
2016/09/14 Javascript
浅析location.href跨窗口调用函数
2016/11/22 Javascript
使用jQuery监听扫码枪输入并禁止手动输入的实现方法(推荐)
2017/03/21 jQuery
BootStrap下的弹出框加载select2框架失败的解决方法
2017/08/31 Javascript
jQuery与vue实现拖动验证码功能
2018/01/30 jQuery
小程序实现搜索界面 小程序实现推荐搜索列表效果
2019/05/18 Javascript
Vue.js项目实战之多语种网站的功能实现(租车)
2019/08/07 Javascript
JS猜数字游戏实例讲解
2020/06/30 Javascript
JavaScript 事件代理需要注意的地方
2020/09/08 Javascript
React中使用Vditor自定义图片详解
2020/12/25 Javascript
python迭代dict的key和value的方法
2018/07/06 Python
Django为窗体加上防机器人的验证码功能过程解析
2019/08/14 Python
python中@property的作用和getter setter的解释
2020/12/22 Python
利用css3-animation实现逐帧动画效果
2016/03/10 HTML / CSS
英国最受欢迎的母婴精品品牌:JoJo Maman BéBé
2021/02/17 全球购物
什么是跨站脚本攻击
2014/12/11 面试题
人力资源总监工作说明
2014/03/03 职场文书
建议书的格式
2014/05/12 职场文书
在职人员跳槽求职信
2015/03/20 职场文书
2015年小学生国庆节演讲稿
2015/07/30 职场文书
外出学习心得体会范文
2016/01/18 职场文书
解决vue $http的get和post请求跨域问题
2021/06/07 Vue.js
Vue实现跑马灯样式文字横向滚动
2021/11/23 Vue.js