利用递归统一化函数参数的不固定数据类型
为了用户调用函数时更方便和灵活,所以我们定义的参数需要不固定数据类型,比如像这样:
mylibs.on('event',fn);
mylibs.on({
'event1':fn1,
'event2':fn2,
'event3':fn3
});
mylibs.on('event1 event2 event3',fn);
这是一个自定义事件的例子,有三种传参的方式:1、事件名+回调 2、传递一个对象包含事件名和回调 3、多个事件名+一个回调
你觉得这个函数怎么写才好呢,也许大多数人首先想到的是统一数据类型再处理具体的逻辑,就像下面这样:
//匹配任何空白符,包括\n,\r,\f,\t,\v等(换行、回车、空格、tab等) var eventSplitter = /\s+/;var mylibs = {on:function(name, callback, context){if(typeof name === 'string'){name = {name:callback};}if (eventSplitter.test(name)) {var names = name.split(eventSplitter),name = {};for (var i = 0, length = names.length; i < length; i++) {name[names[i]] = callback;}}//统一好了数据类型则执行循环(默认数据类型是对象,所以在上面不做判断)for(var key in name){//具体逻辑...... }return this;} };
这种写法看似不错,先统一处理数据类型,解决了参数不同的问题。不过函数看上去稍显臃肿,如果参数再增加几种类型,那么相应的也会在函数体内增加判断语句,并且把具体的逻辑代码放在for循环内也不是一种优雅的做法。
我们可以尝试一下把判断语句提炼出来,写在一个单独的函数里。
var mylibs = {on:function(name, callback, context){name = this.eventsApi(name,callback);for(var key in name){//具体逻辑...... }return this;},eventsApi:function(name,callback){if(typeof name === 'string'){return {name:callback};} if (eventSplitter.test(name)) {var names = name.split(eventSplitter),name = {};for (var i = 0, length = names.length; i < length; i++) {name[names[i]] = callback;}return name;}return name;} };
创建了eventsApi函数来对数据类型做统一处理,很明显on函数已经不臃肿了,2个函数各司其职。但是on函数的具体逻辑代码仍然在for循环内,我们得想办法把它抽离出来。
解决的办法可以利用递归,我们先处理一下eventsApi函数。
eventsApi:function(obj,action,name,rest){if (!name) return true;if(typeof name === 'object'){for(var key in name){obj[action].apply(obj,[key,name[key]].concat(rest));}return false;}if (eventSplitter.test(name)) {var names = name.split(eventSplitter);for (var i = 0, length = names.length; i < length; i++) {obj[action].apply(obj, [names[i]].concat(rest));}return false;}return true; }
是不是眼前一亮,eventsApi函数并没有统一处理数据类型,而是直接调用on函数,此时on函数变成了一个固定数据类型的函数了,其实就是上面第一种传参的形式:一个事件名+回调。
我们看一下完整的代码加深理解吧。
//匹配任何空白符,包括\n,\r,\f,\t,\v等(换行、回车、空格、tab等) var eventSplitter = /\s+/;var mylibs = {on:function(name, callback, context){if (!this.eventsApi(this, 'on', name, [callback, context]) || !callback) return this;//具体逻辑......return this;},eventsApi:function(obj,action,name,rest){if (!name) return true;if(typeof name === 'object'){for(var key in name){obj[action].apply(obj,[key,name[key]].concat(rest));}return false;}if (eventSplitter.test(name)) {var names = name.split(eventSplitter);for (var i = 0, length = names.length; i < length; i++) {obj[action].apply(obj, [names[i]].concat(rest));}return false;}return true;} };//调用: mylibs.on('event',fn); mylibs.on({'event1':fn1,'event2':fn2,'event3':fn3 }); mylibs.on('event1 event2 event3',fn);
转载于:https://www.cnblogs.com/gongshunkai/p/5876700.html
利用递归统一化函数参数的不固定数据类型相关推荐
- php 函数传值_传址_函数参数,php函数的传值与传址(引用)详解
在php中我们函数传值就比较简单了,但可能有些朋友地天真无邪函数传址或引用搞不明白,下面小编来给各位介绍在php中函数传值与传址(引用)介绍,希望对各位有所帮助. php中引用的用法: 1. 变量的引 ...
- php 函数传值_传址_函数参数,php函数的传值与传址(引用)详解_PHP教程
在php中我们函数传值就比较简单了,但可能有些朋友地天真无邪函数传址或引用搞不明白,下面小编来给各位介绍在php中函数传值与传址(引用)介绍,希望对各位有所帮助. php中引用的用法: 1. 变量的引 ...
- 指针用作函数参数、指针型函数和函数指针
指针用作函数参数 以前我们学过的函数参数要么是基本数据类型的变量,要么是类的对象,又或者是数组名,前几讲学到的指针同样可以用作函数参数. 指针作函数形参时,我们调用此函数将实参值传递给形参后,实参和形 ...
- 【C语言函数】 - 库函数、自定义函数、函数参数、函数调用、嵌套调用链式访问、递归与迭代、缓冲区
目录 一.函数是什么 二.C语言中函数的分类 1.如何学会使用库函数 1.1.strcpy 1.2.memset 2.自定义函数 2.1.与库函数的区别 2.2.写一个函数可以找出两个整数的最大值 2 ...
- JavaScript学习笔记(四)---闭包、递归、柯里化函数、继承、深浅拷贝、设计模式
JavaScript学习笔记(四)---闭包.递归.柯里化函数.继承.深浅拷贝.设计模式 1. 匿名函数的使用场景 2.自运行 3.闭包 3.1前提: 3.2闭包 4.函数对象的三种定义方式 5.th ...
- Learn day4 函数参数\变量\闭包\递归
1.函数描述 # ### 函数 """ (1)函数的定义:功能 (包裹一部分代码 实现某一个功能 达成某一个目的) (2)函数特点:可以反复调用,提高代码的复用性,提高开 ...
- 利用递归实现JSON扁平化
1.引入JSON依赖包 把字符串解释成JSON再进行扁平化处理 <dependency> <groupId>com.alibaba< ...
- C语言 函数 (库函数 · 自定义函数 · 函数参数 · 函数调用 · 嵌套调用链式访问 · 递归)
文章目录: 一.函数是什么? 二.库函数 2.1 为什么要有库函数? 2.2 如何学习库函数? 2.3 我们就以 strcpy( ) 函数,来参照文档自学一下: 2.4 总结: 三.自定义函数 3.1 ...
- 二值化函数cvThreshold()参数CV_THRESH_OTSU的疑惑
查看OpenCV文档cvThreshold(),在二值化函数cvThreshold(const CvArr* src, CvArr* dst, double threshold, double max ...
最新文章
- 上海交大、华为海思提出X-volution,发力网络核心基础架构创新
- python 自然语言处理(二) jieba 分词
- 信息系统项目管理师-成本效益分析
- C#——实现IComparable接口、IComparableT 接口、IComparer接口、IComparerT 接口和ComparerT 类DEMO
- matlab修改矩阵元素,怎么修改矩阵中的某些元素 或者简单点说保留矩阵中的元素...
- 使用Axure制作App原型的尺寸设置
- list steam_在 Steam 中国版上玩单机游戏也会受到防沉迷系统管控
- MySQL MVCC 概述
- python批量分析表格_Python统计分析execl文件列表值的方法
- cookie 操作
- 在SQL2008中,如何让id自动生成并自动递增?如何让时间默认生成?
- 操作系统实验报告-多线程编程解决进程间同步和互斥问题
- p1957口算题c语言,洛谷P1957口算练习题题解
- 数据库第6章总结——关系数据理论
- 服务器主板重装系统,简单几步教你如何重新安装系统
- Hark的数据结构与算法练习之计数排序
- uvm学习笔记----适合新手快速学习
- jupyter安装使用
- 今天没有收到农行的笔试通知
- 粒子群算法求解四维病态方程
热门文章
- python模型训练框架_Pytorch-Transformers 1.0发布,支持六个预训练框架,含27个预训练模型...
- 启动失败_启动失败了?
- typechoSQLIte转MySQL_Typecho SQLite与MySQL的数据库切换及解决MySQL连接打开缓慢问题
- 对比原生Node封装的Express路由 和 express框架路由
- C语言日期字符串减少两天,C语言第二天(字符串)
- 初级c 语言题库,初级计算机考试题库
- php资源文件html,nginx 同一域名下分目录配置显示php,html,资源文件
- 猎人能单拿修理机器人图纸_南京创新周麒麟行:他们为铁路配备“体检”机器人...
- java spring 登录验证_浅析Spring Security登录验证流程源码
- 20200316:H指数(leetcode274)