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 相关文章推荐
让textarea控件的滚动条怎是位与最下方
Apr 20 Javascript
js 自制滚动条的小例子
Mar 16 Javascript
AngularJS基础知识笔记之过滤器
May 10 Javascript
jquery采用oop模式class类的使用示例
Jan 22 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
Dec 31 Javascript
Jil,高效的json序列化和反序列化库
Feb 15 Javascript
微信小程序开发图片拖拽实例详解
May 05 Javascript
vue中使用refs定位dom出现undefined的解决方法
Dec 21 Javascript
策略模式实现 Vue 动态表单验证的方法
Sep 16 Javascript
浅谈Vue中render中的h箭头函数
Nov 07 Javascript
微信小程序中网络请求缓存的解决方法
Dec 29 Javascript
VSCode插件安装完成后的配置(常用配置)
Aug 24 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垃圾回收机制引用计数器概念分析
2013/06/24 PHP
PHP开发微信支付的代码分享
2014/05/25 PHP
php实现数组按指定KEY排序的方法
2015/03/30 PHP
php遍历类中包含的所有元素的方法
2015/05/12 PHP
PHP浮点数精度问题汇总
2015/05/13 PHP
关于php中一些字符串总结
2016/05/05 PHP
thinkPHP模板引擎用法示例
2016/12/08 PHP
thinkphp框架page类与bootstrap分页(美化)
2017/06/25 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
PHP删除数组中特定元素的两种方法
2019/02/28 PHP
详解new function(){}和function(){}() 区别分析
2008/03/22 Javascript
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
jQuery的三种$()
2009/12/30 Javascript
jquery 图片截取工具jquery.imagecropper.js
2010/04/09 Javascript
javascript 自定义回调函数示例代码
2014/09/26 Javascript
使用jQuery在对象中缓存选择器的简单方法
2015/06/30 Javascript
WEB前端实现裁剪上传图片功能
2016/10/17 Javascript
Vue响应式原理详解
2017/04/18 Javascript
JS请求servlet功能示例
2017/06/01 Javascript
Angular8 简单表单验证的实现示例
2020/06/03 Javascript
python3.3教程之模拟百度登陆代码分享
2014/01/16 Python
python3中property使用方法详解
2019/04/23 Python
Python中的 sort 和 sorted的用法与区别
2019/08/10 Python
Python socket实现的文件下载器功能示例
2019/11/15 Python
使用Pytorch搭建模型的步骤
2020/11/16 Python
一张图片能隐含千言万语之隐藏你的程序代码
2012/12/13 HTML / CSS
科颜氏美国官网:Kiehl’s美国
2017/01/31 全球购物
中国跨境电商:Tomtop
2017/03/16 全球购物
苏格兰销售女装、男装和童装的连锁店:M&Co
2018/03/16 全球购物
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
会计学生自我鉴定
2014/02/06 职场文书
学生评语大全
2014/04/18 职场文书
学校安全生产月活动总结
2014/07/05 职场文书
2015员工年度考核评语
2015/03/25 职场文书
2015年司机年终工作总结
2015/05/14 职场文书
Springboot如何使用logback实现多环境配置?
2021/06/16 Java/Android