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 相关文章推荐
jquery1.83 之前所有与异步列队相关的模块详细介绍
Nov 13 Javascript
将list转换为json失败的原因
Dec 17 Javascript
js获得网页背景色和字体色的方法
Mar 21 Javascript
JavaScript中使用document.write向页面输出内容实例
Oct 16 Javascript
纯HTML5制作围住神经猫游戏-附源码下载
Aug 23 Javascript
深入解析Javascript闭包的功能及实现方法
Jul 10 Javascript
AngularJS入门教程之ng-class 指令用法
Aug 01 Javascript
Ionic 2 实现列表滑动删除按钮的方法
Jan 22 Javascript
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
Dec 06 Javascript
在 Linux/Unix 中不重启 Vim 而重新加载 .vimrc 文件的流程
Mar 21 Javascript
vue框架中props的typescript用法详解
Feb 17 Javascript
JavaScript this关键字指向常用情况解析
Sep 02 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 url路由入门实例
2014/04/23 PHP
PHP中include()与require()的区别说明
2017/02/14 PHP
PHP多种序列化/反序列化的方法详解
2017/06/23 PHP
PHP中一个有趣的preg_replace函数详解
2018/08/15 PHP
javascript 写类方式之一
2009/07/05 Javascript
JQuery 表格操作(交替显示、拖动表格行、选择行等)
2009/07/29 Javascript
SWFObject 2.1以上版本语法介绍
2010/07/10 Javascript
js鼠标点击事件在各个浏览器中的写法及Event对象属性介绍
2013/01/24 Javascript
jquery淡化版banner异步图片文字效果切换图片特效
2014/04/08 Javascript
javascript中对变量类型的判断方法
2015/08/09 Javascript
AngularJs中route的使用方法和配置
2016/02/04 Javascript
基于jQuery实现动态搜索显示功能
2016/05/05 Javascript
JS+CSS3模拟溢出滚动效果
2016/08/12 Javascript
从0开始学Vue
2016/10/27 Javascript
Vue项目使用localStorage+Vuex保存用户登录信息
2019/05/27 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
vue-socket.io接收不到数据问题的解决方法
2020/05/13 Javascript
npm ci命令的基本使用方法
2020/09/20 Javascript
解决Vue大括号字符换行踩的坑
2020/11/09 Javascript
[47:02]2018DOTA2亚洲邀请赛3月29日 小组赛B组 VP VS paiN
2018/03/30 DOTA
在Python中处理字符串之isdigit()方法的使用
2015/05/18 Python
Python中操作符重载用法分析
2016/04/29 Python
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
2019/01/05 Python
Django {{ MEDIA_URL }}无法显示图片的解决方式
2020/04/07 Python
HTML5新增的Css选择器、伪类介绍
2013/08/07 HTML / CSS
canvas 基础之图像处理的使用
2020/04/10 HTML / CSS
俄罗斯领先的移动和数字设备在线商店:Svyaznoy.ru
2020/12/21 全球购物
求职信范文英文版
2014/01/05 职场文书
法学院方阵解说词
2014/01/29 职场文书
环境建议书
2015/02/04 职场文书
加班费申请报告
2015/05/15 职场文书
入党申请书怎么写?
2019/06/11 职场文书
2019交通安全宣传标语集锦!
2019/06/28 职场文书
Golang: 内建容器的用法
2021/05/05 Golang
聊聊Lombok中的@Builder注解使用教程
2021/11/17 Java/Android