javascript下利用arguments实现string.format函数


Posted in Javascript onAugust 24, 2010

下面摘抄一下源码,深入分析一下他的设计实现思路:

function format(string) { 
var args = arguments; 
var pattern = new RegExp("%([1-" + arguments.length + "])", "g"); 
return String(string).replace(pattern, function(match, index) { 
return args[index]; 
}); 
};

通过format函数,下面的代码:
format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear");

就会返回:"And the papers want to know whose shirt you wear" 。
果然有点像c#下string.format函数一样传参调用。
总体说来,好像真没什么技术含量。但是真的没有技术含量吗?楼猪大胆根据自己对javascript和arguments的浅薄认识和理解,再来剖析一下这段程序:
1、正则表达式
非常巧妙地new了一个以%开头匹配1到argument个数的一个正则pattern,这个正则是下面第2点字符串替换的重要前提准备;
2、string的Replace函数
replace函数的第二个参数是function,这点非常令人“意外”。通过定义,变量args实际上就是arguments,接着通过args[index]就能取到第index个参数,而且index>=1且index<arguments.length又能保证获取参数的正确。

函数如此短小精悍,和强大的功能形成巨大反差,令人拍案。
可能有许多像楼猪一样被c#惯坏的开发者,会迷恋c#的string.format的写法(大部分还是使用习惯在作怪吧?),好事楼猪稍微改动了一下源码:

function format(string) { 
var args = arguments; 
var pattern = new RegExp("{([0-" + arguments.length + "])}", "g"); 
return String(string).replace(pattern, function(match, index) { 
var currentIndex = parseInt(index); 
if (currentIndex + 1 > args.length || currentIndex < 0) { 
throw new Error("参数索引出错"); 
} 
return args[currentIndex + 1]; 
}); 
}; 
document.write(format("And the {0} want to know whose {1} you {2}", "papers", "shirt", "wear"));//大括号,索引从0开始...

这样看上去就可以像c#的编写风格一样调用format函数了。
最后查看此文的写作时间是在2008年,楼猪在08年的时候觉悟还算蛮高的,正自发努力学习javascript中,但是对arguments认识还很稚嫩,虽然已经知道可以在自定义事件中通过它来定义createFunction函数,用createFunction函数来构造无参数的function给事件使用,但是当时一直抑郁“只知其形,不得其实”。看完Andrew的佳作,豁然开朗,虽然反应迟钝后知后觉,依然感到无比振奋和欣慰。

你看一下Andrew Tetlaw的原文吧。其实下面已经有人指出format函数参数超出9以后,该函数就不起作用了,然后还给出了解决方法:

eric d. Hi, thanks for that brilliant article. Made a lot of things a lot clearer!
Note: new RegExp("%([1-" + arguments.length + "])", "g"); will fail passed 9 arguments (the regexp would be "%([1-10])" so it will only match %0 and %1).

I think an easy fix would be something like:
function format(string) { var args = arguments; var pattern = new RegExp("%([0-9]+)", "g"); return String(string).replace(pattern, function(match, index) { if (index == 0 || index >= args.length) throw "Invalid index in format string"; return args[index]; }); };
(Sorry for nitpicking, I understand it was only an example and brevety is the main objective, but its a great function to have)

Posted on: January 20th 2009, 12:01 am

Javascript 相关文章推荐
javascript 定义新对象方法
Feb 20 Javascript
一个Action如何调用两个不同的方法
May 22 Javascript
js实现下拉框选择要显示图片的方法
Feb 16 Javascript
用jQuery.ajaxSetup实现对请求和响应数据的过滤
Dec 20 Javascript
Mongoose学习全面理解(推荐)
Jan 21 Javascript
详解Vue.js搭建路由报错 router.map is not a function
Jun 27 Javascript
vue-cli 引入、配置axios的方法
May 08 Javascript
eslint 的三大通用规则详解
May 16 Javascript
JS前端知识点 运算符优先级,URL编码与解码,String,Math,arguments操作整理总结
Jun 27 Javascript
如何对react hooks进行单元测试的方法
Aug 14 Javascript
vue商城中商品“筛选器”功能的实现代码
Jul 01 Javascript
交互式可视化js库gojs使用介绍及技巧
Feb 18 Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件
Aug 24 #Javascript
js null,undefined,字符串小结
Aug 21 #Javascript
javascript中的float运算精度实例分析
Aug 21 #Javascript
Firebug入门指南(Firefox浏览器)
Aug 21 #Javascript
jquery插件之easing 动态菜单
Aug 21 #Javascript
url地址自动加#号问题说明
Aug 21 #Javascript
jquery中输入验证中一个不错的效果
Aug 21 #Javascript
You might like
精通php的十大要点(上)
2009/02/04 PHP
php比较两个绝对时间的大小
2014/01/31 PHP
PHP中使用TCPDF生成PDF文档实例
2014/07/01 PHP
php密码生成类实例
2014/09/24 PHP
XHProf报告字段含义的解析
2016/05/17 PHP
PHP连接MySQL数据库的三种方式实例分析【mysql、mysqli、pdo】
2019/11/04 PHP
javascript removeChild 使用注意事项
2009/04/11 Javascript
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
jquery中的 $(&quot;#jb51&quot;)与document.getElementById(&quot;jb51&quot;) 的区别
2011/07/26 Javascript
分享精心挑选的23款美轮美奂的jQuery 图片特效插件
2012/08/14 Javascript
深入理解JSON数据源格式
2014/01/10 Javascript
判断字符串的长度(优化版)中文占两个字符
2014/10/30 Javascript
js实现创建删除html元素小结
2015/09/30 Javascript
JS控制弹出悬浮窗口(一览画面)的实例代码
2016/05/30 Javascript
JS仿hao123导航页面图片轮播效果
2016/09/01 Javascript
深入理解requestAnimationFrame的动画循环
2016/09/20 Javascript
详解Vue 实例中的生命周期钩子
2017/03/21 Javascript
Nodejs回调加超时限制两种实现方法
2017/06/09 NodeJs
JS表单提交验证、input(type=number) 去三角 刷新验证码
2017/06/21 Javascript
详解webpack + vue + node 打造单页面(入门篇)
2017/09/23 Javascript
Python中使用动态变量名的方法
2014/05/06 Python
Python3通过Luhn算法快速验证信用卡卡号的方法
2015/05/14 Python
Python中unittest模块做UT(单元测试)使用实例
2015/06/12 Python
Python实现八大排序算法
2016/08/13 Python
python日志模块logbook使用方法
2019/09/19 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
2019/09/25 Python
Python实现中值滤波去噪方式
2019/12/18 Python
python 实现保存最新的三份文件,其余的都删掉
2019/12/22 Python
Python定时从Mysql提取数据存入Redis的实现
2020/05/03 Python
DOUGLAS荷兰:购买香水和化妆品
2020/10/24 全球购物
咖啡馆创业计划书
2014/01/26 职场文书
工业设计毕业生自荐信
2014/04/13 职场文书
繁星春水读书笔记
2015/06/30 职场文书
mysql创建存储过程及函数详解
2021/12/04 MySQL
redis数据结构之压缩列表
2022/03/21 Redis
Python使用Beautiful Soup(BS4)库解析HTML和XML
2022/06/05 Python