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 相关文章推荐
JS实现仿微博可关闭弹出层效果
Sep 21 Javascript
JS中sort函数排序用法实例分析
Jun 16 Javascript
JS实现鼠标滑过显示边框的菜单效果
Sep 21 Javascript
微信小程序 视图容器组件的详解及实例代码
Jan 19 Javascript
JS中实现函数return多个返回值的实例
Feb 21 Javascript
Vue实现购物车功能
Apr 27 Javascript
javascript基于定时器实现进度条功能实例
Oct 13 Javascript
js+css实现打字效果
Jun 24 Javascript
详解Vue webapp项目通过HBulider打包原生APP(vue+webpack+HBulider)
Feb 02 Javascript
jQuery实现ajax的嵌套请求案例分析
Feb 16 jQuery
vue实现简单瀑布流布局
May 28 Javascript
js实现手表表盘时钟与圆周运动
Sep 18 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 正则匹配函数体
2009/08/25 PHP
php date与gmdate的获取日期的区别
2010/02/08 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
PHP PDOStatement::getAttribute讲解
2019/02/01 PHP
PHP const定义常量及global定义全局常量实例解析
2020/05/28 PHP
Javascript 通过json自动生成Dom的代码
2010/04/01 Javascript
菜鸟javascript基础整理1
2010/12/06 Javascript
jqeury eval将字符串转换json的方法
2011/01/20 Javascript
JavaScript实现自己的DOM选择器原理及代码
2013/03/04 Javascript
jquery获取节点名称
2015/04/26 Javascript
jQuery插件slider实现拖动滑块选取价格范围
2015/04/30 Javascript
JS中的数组方法笔记整理
2016/07/26 Javascript
jQuery dataTables与jQuery UI 对话框dialog的使用教程
2016/09/02 Javascript
AngularJS实现用户登录状态判断的方法(Model添加拦截过滤器,路由增加限制)
2016/12/12 Javascript
Nodejs中Express 常用中间件 body-parser 实现解析
2017/05/22 NodeJs
vue复合组件实现注册表单功能
2017/11/06 Javascript
用ES6写全屏滚动插件的示例代码
2018/05/02 Javascript
vue 刷新之后 嵌套路由不变 重新渲染页面的方法
2018/09/13 Javascript
JS实现求5的阶乘示例
2019/01/21 Javascript
[02:40]DOTA2超级联赛专访430 从小就爱玩对抗性游戏
2013/06/18 DOTA
使用setup.py安装python包和卸载python包的方法
2013/11/27 Python
Python Requests安装与简单运用
2016/04/07 Python
浅析PHP与Python进行数据交互
2018/05/15 Python
python爬虫之线程池和进程池功能与用法详解
2018/08/02 Python
使用Keras画神经网络准确性图教程
2020/06/15 Python
解决tensorflow/keras时出现数组维度不匹配问题
2020/06/29 Python
关于HTML5语义标签的实践(blog页面)
2016/07/12 HTML / CSS
美国最大的袜子制造商和零售商:Renfro Socks
2017/09/03 全球购物
印度在线购物网站:Paytmmall
2019/07/24 全球购物
写出SQL四条最基本的数据操作语句(DML)
2012/12/12 面试题
请编程遍历页面上所有 TextBox 控件并给它赋值为 string.Empty
2015/12/03 面试题
电力公司个人求职信范文
2014/02/04 职场文书
经理管理专业毕业自荐书范文
2014/02/12 职场文书
技术总监管理岗位职责
2014/03/09 职场文书
团队经理竞聘书
2014/03/31 职场文书
教师见习总结范文
2015/06/23 职场文书