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

 更新时间:2010年08月24日 02:01:05   作者:  
sitepoint上看到Andrew Tetlaw在08年写的文章arguments: A JavaScript Oddity,阅读之后,除了对arguments温故知新一遍以外,印象最深刻的还是Andrew的第一个函数实现的string.format功能。
下面摘抄一下源码,深入分析一下他的设计实现思路:
复制代码 代码如下:

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 &gt; args.length || currentIndex &lt; 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

相关文章

  • openlayers实现图标拖动获取坐标

    openlayers实现图标拖动获取坐标

    这篇文章主要为大家详细介绍了openlayers实现图标拖动获取坐标,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • 黑帽seo劫持程序,js劫持搜索引擎代码

    黑帽seo劫持程序,js劫持搜索引擎代码

    今天在浏览网页时无意中发现了这段JS劫持搜索引擎代码。劫持搜索引擎正常搜索过来的流量,这是黑帽seo常用的劫持方法。特意解密出来供大家了解其劫持原理。感兴趣的朋友一起学习学习吧
    2015-09-09
  • js实现当鼠标移到表格上时显示这一格全部内容的代码

    js实现当鼠标移到表格上时显示这一格全部内容的代码

    下面小编就为大家带来一篇js实现当鼠标移到表格上时显示这一格全部内容的代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • 微信小程序视图控件与bindtap之间的问题的解决

    微信小程序视图控件与bindtap之间的问题的解决

    这篇文章主要介绍了微信小程序视图控件与bindtap之间的问题的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • js图片延迟技术一般的思路与示例

    js图片延迟技术一般的思路与示例

    现将img元素对应的src路径设置为背景图片,而该img所对应的url路径存放在一个自设的属性中
    2014-03-03
  • ASP中进行HTML数据及JS数据编码函数

    ASP中进行HTML数据及JS数据编码函数

    在有些时候我们无法控制乱码的出现, 比如发送邮件的时候有些邮件显示乱码, 比如Ajax返回数据总是乱码. 怎么办?
    2009-11-11
  • 如何使用JavaScript快速创建一个1到100的数组

    如何使用JavaScript快速创建一个1到100的数组

    平时写代码时,我们会生产一些测试用的数组数据,比如[1,100]的数组值,下面这篇文章主要给大家介绍了关于如何使用JavaScript快速创建一个1到100数组的相关资料,需要的朋友可以参考下
    2022-08-08
  • hash特点、hashchange事件介绍及其常见应用场景

    hash特点、hashchange事件介绍及其常见应用场景

    浅析hash特点、hashchange事件介绍及其常见应用场景(不同hash对应不同事件处理、移动端大图展示状态后退页面问题、原生轻应用头部后退问题、移动端自带返回按钮二次确认问题),hashchange和popstate事件触发条件
    2023-11-11
  • JS前端解压zip的方法和技巧分享

    JS前端解压zip的方法和技巧分享

    这篇文章主要介绍了JS前端解压zip的方法和技巧,业务中有时候需要获取某个 zip 压缩包内的文件内容展示到前端,在 zip 包体积不是那么大的时候并且不涉及压缩包解密的时候,可以考虑纯前端方案,需要的朋友可以参考下
    2024-03-03
  • jquery删除ID为sNews的tr元素的内容

    jquery删除ID为sNews的tr元素的内容

    这篇文章主要介绍了删除ID为sNews的索引为JQID的tr元素里的内容,需要的朋友可以参考下
    2014-04-04

最新评论