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 相关文章推荐
简单时间提示DEMO从0开始一直进行计时
Nov 19 Javascript
jQuery实现动态表单验证时文本框抖动效果完整实例
Aug 21 Javascript
Angular.js与Bootstrap相结合实现手风琴菜单代码
Apr 13 Javascript
Vue.js中数组变动的检测详解
Oct 12 Javascript
Bootstrap基本组件学习笔记之导航(10)
Dec 07 Javascript
原生JS实现图片轮播效果
Dec 26 Javascript
ES6正则表达式扩展笔记
Jul 25 Javascript
angularjs实现table增加tr的方法
Feb 27 Javascript
小程序异步问题之多个网络请求依次执行并依次收集请求结果
May 05 Javascript
Vue项目环境搭建详细总结
Sep 26 Javascript
JS自定义对象创建与简单使用方法示例
Jan 15 Javascript
jQuery实现全选按钮
Jan 01 jQuery
基于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
安装APACHE
2007/01/15 PHP
改变Apache端口等配置修改方法
2008/06/05 PHP
使用symfony命令创建项目的方法
2016/03/17 PHP
再论Javascript下字符串连接的性能
2011/03/05 Javascript
jQuery1.6 使用方法一
2011/11/23 Javascript
如何制作浮动广告 JavaScript制作浮动广告代码
2012/12/30 Javascript
JQuery操作iframe父页面与子页面的元素与方法(实例讲解)
2013/11/20 Javascript
javascript实现在网页任意处点左键弹出隐藏菜单的方法
2015/05/13 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
jQuery Ajax 全局调用封装实例代码详解
2016/06/02 Javascript
JavaScript中ES6 Babel正确安装过程
2016/07/18 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
2017/03/14 Javascript
jQuery中的for循环var与let的区别
2018/04/21 jQuery
详解使用Nuxt.js快速搭建服务端渲染(SSR)应用
2019/03/13 Javascript
使用vue完成微信公众号网页小记(推荐)
2019/04/28 Javascript
layui 监听select选择 获取当前select的ID名称方法
2019/09/24 Javascript
深度解读vue-resize的具体用法
2020/07/08 Javascript
js仿京东放大镜效果
2020/08/09 Javascript
你不知道的SpringBoot与Vue部署解决方案
2020/11/09 Javascript
使用python提取html文件中的特定数据的实现代码
2013/03/24 Python
python matlibplot绘制多条曲线图
2021/02/19 Python
pyspark.sql.DataFrame与pandas.DataFrame之间的相互转换实例
2018/08/02 Python
为什么Python中没有&quot;a++&quot;这种写法
2018/11/27 Python
Python实现蒙特卡洛算法小实验过程详解
2019/07/12 Python
jupyter notebook oepncv 显示一张图像的实现
2020/04/24 Python
python线程里哪种模块比较适合
2020/08/02 Python
python 日志模块logging的使用场景及示例
2021/01/04 Python
python UIAutomator2使用超详细教程
2021/02/19 Python
类的核心特性有哪些
2014/01/01 面试题
财务会计应届生求职信
2013/11/24 职场文书
家长会学生家长演讲稿
2013/12/29 职场文书
公司培训欢迎词
2014/01/10 职场文书
小学家长学校培训材料
2014/08/24 职场文书
小学六一儿童节活动方案
2014/08/27 职场文书
学校食品安全责任书
2015/01/29 职场文书
GoFrame基于性能测试得知grpool使用场景
2022/06/21 Golang