CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
(图)邪恶的韩国UMPC 使用 Java 编写数据库应用新规范
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Web 开发 >  JavaScript

发布了一个高性能的format实现

楼主hax(海曦)2006-11-27 14:16:53 在 Web 开发 / JavaScript 提问

许多JS工具库或者框架都提供了字符串格式化的方法,如Atlas,典型代码如:  
  String.format('Hello   {0}!',   'world')   返回   "Hello   world!"  
   
  但是没有一个有像这个实现   http://blog.csdn.net/hax/archive/2006/11/27/1416692.aspx   那样好的性能,特别是在有大量占位符时性能不会快速衰退。观察其实现代码,每次format调用所作的只是一次Array.join然后一次String.replace(regex,   string)的操作,两者都是js中的native方法,而不会有任何自定义函数调用。  
   
  用法:    
  1.   String.format('Hello   $1!',   'world')   或   'Hello   $1!'.format('world')  
  2.   如果要包含$字符,需写成$$,如   '$$version   $1$$'.format('1.0')   返回$version   1.0$  
  3.   字符串内不能包含字符0x1f(ASCII和Unicode中所谓数据分隔符,实际中几乎不会使用,可能只有一些很古老的自定义数据文件格式会用到)  
   
  好的想法要给大家共享,所以发布出来,也供高手参详。  
   
  注意,代码以GPL/LGPL的许可证发布,通常可自由使用。如需以其他方式使用,需获得作者我的同意。 问题点数:200、回复次数:68Top

1 楼myvicy(我来也!)回复于 2006-11-27 14:23:02 得分 9

顶就一个字。Top

2 楼zs178(zh-cn)回复于 2006-11-27 14:41:16 得分 5

嘿嘿,楼主好人啊,撒200分  
  顶了~~~~~~~Top

3 楼bigman_lfj(盐水小鱼)回复于 2006-11-27 14:50:43 得分 5

赫赫,顶一下Top

4 楼woneinwy(★★★★★★★★★★@しǒひê)回复于 2006-11-27 14:55:07 得分 5

接分不留名Top

5 楼mh_rock(Rock 努力学习C#)回复于 2006-11-27 15:03:51 得分 5

顶一下,接分Top

6 楼CutBug(.NetZergling)回复于 2006-11-27 15:06:05 得分 5

JFTop

7 楼chenguang79(小虫)回复于 2006-11-27 15:06:35 得分 4

感谢楼主共享Top

8 楼ttyp(@http://www.cnblogs.com/ttyp/)回复于 2006-11-27 15:24:41 得分 10

是不错,但是对你发布的GPL不是很欣赏,为什么不是BSD,如果需要你的同意,我宁愿使用自己编写的,尽管慢点,呵呵Top

9 楼hbhbhbhbhb1021(天外水火(我要多努力))回复于 2006-11-27 15:27:22 得分 10

hax   (海曦)兄弟,你博客上写的比较乱,怕是很多人都不会去仔细研究,第一眼看上去我也是没看明白,把你的整理成了可以看到结果的例子,大家一起研究看看  
  <script   language=javascript>  
    if   (!String._FORMAT_SEPARATOR){  
                  String._FORMAT_SEPARATOR   =   String.fromCharCode(0x1f);  
                  String._FORMAT_ARGS_PATTERN   =   new   RegExp('^[^'   +   String._FORMAT_SEPARATOR   +   ']*'   +   new   Array(100).join('(?:.([^'   +   String._FORMAT_SEPARATOR   +   ']*))?'));  
          }  
          if   (!String.format)  
          String.format   =   function   (s){  
                  return   Array.prototype.join.call(arguments,   String._FORMAT_SEPARATOR).replace(String._FORMAT_ARGS_PATTERN,   s);  
          }  
          if   (!''.format)  
          String.prototype.format   =   function   (){  
                  return   (String._FORMAT_SEPARATOR   +Array.prototype.join.call(arguments,   String._FORMAT_SEPARATOR)).replace(String._FORMAT_ARGS_PATTERN,   this);  
          }  
   
  var   name   =   'world';  
  var   result   =   'Hello   $1!'.format(name);  
  alert(result)  
   
  var   letters   =   String.format('$1$2$3$4$5$6$7$8$9$10$11$12$13$14$15$16$17$18$19$20$21$22$23$24$25$26',   'a',   'b',   'c',   'd',   'e',   'f',   'g',   'h',   'i',   'j',   'k',   'l',   'm',   'n',   'o',   'p',   'q',   'r',   's',   't',   'u',   'v',   'w',   'x',   'y',   'z');  
  alert(letters)  
  </script>Top

10 楼descreekert(descreekert)回复于 2006-11-27 15:37:30 得分 3

收藏,学习Top

11 楼hbhbhbhbhb1021(天外水火(我要多努力))回复于 2006-11-27 15:38:34 得分 10

这样不好吗?为什么占位符编号到几,就要几次,高版本的浏览器replace函数支持的,hax   (海曦)兄弟你的正则预查同样需要高版本的浏览器。  
  var   temp="'a',   'b',   'c',   'd',   'e',   'f',   'g',   'h',   'i',   'j',   'k',   'l',   'm',   'n',   'o',   'p',   'q',   'r',   's',   't',   'u',   'v',   'w',   'x',   'y',   'z'".replace(/[\'   ]/g,'').split(",")  
  var   i=0;  
  letters='$1$2$3$4$5$6$7$8$9$10$11$12$13$14$15$16$17$18$19$20$21$22$23$24$25$26'.replace(/\$\d{1,2}/g,function(a){return   temp[i++]})  
  alert(letters)Top

12 楼bejon(阿牛[如果我懂,必坦诚相告;如果您懂,请不吝赐教。])回复于 2006-11-27 15:42:39 得分 3

收藏,学习Top

13 楼ttyp(@http://www.cnblogs.com/ttyp/)回复于 2006-11-27 15:45:29 得分 10

hbhbhbhbhb1021(天外水火(我要多努力))    
   
  你用function(a){return   temp[i++]})还是需要横多次替换啊Top

14 楼hax(海曦)回复于 2006-11-27 15:46:15 得分 0

To   ttyp:  
   
  我并不排斥revised   BSD,且revised   BSD与GPL是兼容的。使用GPL/LGPL,只是因为我更欣赏GPL/LGPL推广Free   Software的理念,且这小段代码是从我的PIES项目中攫取,该项目采用GPL/LGPL许可证。  
   
  LGPL还是很宽松的,一般而言你不必获得我的许可,其实对于这样一小段脚本,我也没有考虑过怎样的用途是不合该许可证而需要得到我的同意的。这只是一小段代码而已,我只是随时传播自由的声明也。Top

15 楼hbhbhbhbhb1021(天外水火(我要多努力))回复于 2006-11-27 15:52:11 得分 10

to   ttyp  
  我觉得应该和replace('$1','a').replace('$2','b')这种不同吧,至少匹配的时候不会一次全部匹配结束在重头匹配,就是说lastIndex属性不用移动那么多次,只走一遍Top

16 楼hax(海曦)回复于 2006-11-27 16:00:06 得分 0

To   hbhbhbhbhb1021:  
   
  不清楚你在说哪个问题,我所指的是各种实现,包括不太好的实现。如果你是说高版本可以用自定义函数替换,而不需要调用多次replace,则ttyp已经回答你了   :)    
   
  至于浏览器版本问题,我在blog上已经写了,如jscript   5.5以下的(如ie   5.0默认所带jscript   5.0)确实不行。但现在还使用非ecmascript   3的js引擎已经很稀少了,可忽略之。即使在某些商用环境中,不能升级浏览器如ie   5.0,至少也可只升级脚本引擎的。Top

17 楼ttyp(@http://www.cnblogs.com/ttyp/)回复于 2006-11-27 16:00:47 得分 10

TO   hax:  
   
  LGPL是可以转换为商业代码的,有赚取广大free   software思想之嫌疑,相对的BSD,appache似乎自由度更大一点,还有个啥协议,只要使用者申明作者的就能使用,忘记名字了。  
   
  TO   hbhbhbhbhb1021(天外水火(我要多努力))   :  
   
  是不同,但是用了function,至少会产生很多临时变量和堆栈吧Top

18 楼hax(海曦)回复于 2006-11-27 16:08:53 得分 0

To   (hb){5}1021   (名字太长,我用正则来写,呵呵):  
   
  性能下降的关键在于自定义函数还是要被调用n次,例如"$1   $1   $1   $1".replace(/[$][0-9]/,   f),f还是被调用了4次。而且随占位符的增加至少是线形增长。  
   
  而我所写的实现始终只有一次Array.join和String.replace,且用到正则的复杂度是恒定的,因此整体性能是常数的。Top

19 楼Go_Rush(我的技术博客http://ashun.cnblogs.com/)回复于 2006-11-27 16:45:08 得分 2

支持一下。楼主   JavaScript功底确实很厉害。  
   
  我是看晕了Top

20 楼galant2008(無賴)回复于 2006-11-27 16:58:34 得分 2

学习一下Top

21 楼jiangtao088(不够专业)回复于 2006-11-27 17:09:27 得分 2

markTop

22 楼hbhbhbhbhb1021(天外水火(我要多努力))回复于 2006-11-27 17:28:54 得分 2

的确很经典,:)Top

23 楼mingxuan3000(铭轩)回复于 2006-11-27 18:27:51 得分 2

学习Top

24 楼hax(海曦)回复于 2006-11-27 18:30:15 得分 0

经典不敢。只是抛砖引玉一下,如何在螺丝壳里做道场,其要义就是充分利用螺丝壳。  
   
  这个代码片段其实是我在写logging的时候的产物,下一次我会把整个log4js拿出来与大家探讨,如何避免log对性能的影响。Top

25 楼ttyp(@http://www.cnblogs.com/ttyp/)回复于 2006-11-27 18:33:35 得分 2

非常期待log4jsTop

26 楼hbhbhbhbhb1021(天外水火(我要多努力))回复于 2006-11-27 19:45:23 得分 2

是哦,效率一般都出在IO上,前几天我就遇到了这个问题,日志打太多了,速度慢。Top

27 楼btbtd(签名加载中...请稍候...单击...双击ok)回复于 2006-11-27 20:39:43 得分 2

直接进行二进制操作才见效率,,JS就算了吧.Top

28 楼Love_My()回复于 2006-11-27 20:52:21 得分 2

....   直接接分Top

29 楼precipitant(塞北的雪)回复于 2006-11-28 08:14:57 得分 2

先标记,有空研究。Top

30 楼myminimouse(坚决不用baidu)回复于 2006-11-28 08:24:02 得分 2

看看Top

31 楼royeleo(煨灶猫||(只要一颗★))回复于 2006-11-28 09:46:39 得分 2

赫赫,顶一下Top

32 楼mldswt(一个普通老百姓的要求:农妇,果园,有点田。)回复于 2006-11-28 10:36:35 得分 2

学习中Top

33 楼qiuyi21()回复于 2006-11-28 11:52:08 得分 2

很好Top

34 楼microjunjun()回复于 2006-11-28 14:19:22 得分 2

formatTop

35 楼yousite1(国雾)回复于 2006-11-28 15:29:24 得分 2

经典,楼主谢谢Top

36 楼huhh2004(冰石)回复于 2006-11-28 16:00:42 得分 2

mark  
  Top

37 楼fantiny(卖身不卖艺的菜鸟)回复于 2006-11-28 16:45:44 得分 2

占位看看Top

38 楼championmajian(小马||目前酒力:白的半斤,啤的3瓶)回复于 2006-11-28 17:14:50 得分 2

markTop

39 楼mb459()回复于 2006-11-28 17:57:08 得分 2

学习Top

40 楼ShinStone()回复于 2006-11-28 17:58:20 得分 2

好东西  
  Top

41 楼GavinLv(Gavin.Lv.)回复于 2006-11-28 19:49:35 得分 2

顶Top

42 楼handsomebird123(handsomebird123)回复于 2006-11-29 10:00:27 得分 2

markTop

43 楼zzzsea(兴,百姓苦。亡,百兴苦)回复于 2006-11-29 10:30:11 得分 2

扫分   MarkTop

44 楼brothercat(猫猫 ^_^)回复于 2006-11-29 10:39:39 得分 2

不说了撒,仰慕ing...  
   
  算了,我打算换版块了,非技术讨论版怎么样?^_^Top

45 楼w78z007()回复于 2006-11-29 10:47:39 得分 2

为什么要换啊,我们这些后辈还要您的支持呢Top

46 楼liuph3000()回复于 2006-11-29 10:53:08 得分 2

markTop

47 楼daluoboequalto(大萝卜)回复于 2006-11-29 11:48:10 得分 2

是好东西,  
  螺丝壳里做道场。Top

48 楼xuancaoer(当回复为'mark'的时候请别给我分)回复于 2006-11-29 12:31:58 得分 2

markTop

49 楼gzty(【风逍遥】123笨小孩天天快乐)回复于 2006-11-29 13:05:44 得分 2

是好东西,  
  螺丝壳里做道场  
   
  ==========================  
  什么意思啊  
  看不懂`:(Top

50 楼championmajian(小马||目前酒力:白的半斤,啤的3瓶)回复于 2006-11-29 13:14:13 得分 2

markTop

51 楼bamboo_2001(千棵竹)回复于 2006-11-29 15:49:57 得分 2

okTop

52 楼zoloao()回复于 2006-11-29 16:20:44 得分 2

是好东西,  
  螺丝壳里做道场  
   
  ==========================  
  什么意思啊  
  看不懂`:(  
   
  ==========================  
  小题大做啊  
  Top

53 楼afoskoo(暂停打印)回复于 2006-11-29 17:16:26 得分 2

看不懂到底format个啥。  
  String.format('Hello   {0}!',   'world')   返回   "Hello   world!"   这有什么意思啊?  
  楼主发两个有价值的例子看看啊。Top

54 楼li1229363()回复于 2006-11-29 17:42:05 得分 2

接分+标记~LZ大方!Top

55 楼muxrwc(厕所宣言:信念永不变,追猫永不弃。)回复于 2006-11-29 17:52:35 得分 2

轻轻的UP小下,然后在悄悄的离开。。Top

56 楼okitgo(IT浪涛儿)回复于 2006-11-29 19:13:11 得分 2

upTop

57 楼nanfeng916()回复于 2006-11-29 21:29:48 得分 2

顶起来,Top

58 楼emilchan6k(emilchan)回复于 2006-11-29 22:00:53 得分 2

jf,markTop

59 楼woyingjie(Hobo)回复于 2006-11-30 09:09:16 得分 10

var   arr   =   new   Array();  
  var   a   =   new   Date();  
   
  for   (var   i=0;   i<10000;   i++)  
  {  
  arr.join(String.format("$1,$2,$3$4",   "a",   "b",   "c",   "d"));  
  }  
   
  alert(new   Date()     -   a);   //705毫秒  
   
   
  var   b   =   new   Date();  
   
  for   (i=0;   i<10000;   i++)  
  {  
  arr.join("a"   +   ","   +   "b"   +   ","   +   "c"   +   "d");  
  }  
   
  alert(new   Date()     -   b);   //344毫秒Top

60 楼squallqiu(刮风还下雨)回复于 2006-11-30 09:11:47 得分 2

不错。仔细看看。Top

61 楼hax(海曦)回复于 2006-11-30 09:12:54 得分 0

楼上的,用字符串连接当然最快,format是为了提高代码可读性,在此前提下尽量提速。Top

62 楼hax(海曦)回复于 2006-11-30 13:08:37 得分 0

补充一下,今天看到有人问要在第一个参数后跟一个1怎么办,因为不能写成   '$11'.format('a')。  
  这个其实很简单,写成'$011'.format('a')即可,返回结果为'a1'。Top

63 楼shjohnson()回复于 2006-11-30 13:11:36 得分 2

顶你个肺Top

64 楼FEB15(张郎)回复于 2006-11-30 13:16:22 得分 2

markTop

65 楼qqulijun(探讨中国软件)回复于 2006-11-30 13:52:10 得分 2

感谢楼主Top

66 楼wuyan_xjb()回复于 2006-12-07 17:16:07 得分 0

log4js   ?   好像早就有了吧?Top

67 楼meizz(梅花雪)回复于 2006-12-16 17:44:51 得分 0

'$1$2$3$4$5$6$7$8$9$10'.format('a');  
  这样的替换,应该的结果是   a$2$3$4$5$6$7$8$9$10  
  而你给的结果却只是一个字母   a   ,好象不太对吧!Top

68 楼meizz(梅花雪)回复于 2006-12-16 18:18:52 得分 0

与你这样不正确且要求颇多的方法相比,我情愿要一个效率差些,但是正确,且兼容低版本浏览器的方法:  
   
  String.prototype.format   =   function(str)  
  {  
          if(arguments.length==0)   return   this;  
          try  
          {  
                  var   A   =   arguments;  
                  return   this.replace(/\{(\d+)\}/g,   function(a,   b){return   A[b]||a});  
          }  
          catch   (ex)  
          {  
                  for(var   i=0,   s=this,   n=arguments.length;   i<n;   i++)  
                  {  
                          s   =   s.split("{"+   i   +"}").join(arguments[i]);  
                  }  
          }  
          return   s;  
  }Top

相关问题

关键词

得分解答快速导航

  • 帖主:hax
  • myvicy
  • zs178
  • bigman_lfj
  • woneinwy
  • mh_rock
  • CutBug
  • chenguang79
  • ttyp
  • hbhbhbhbhb1021
  • descreekert
  • hbhbhbhbhb1021
  • bejon
  • ttyp
  • hbhbhbhbhb1021
  • ttyp
  • Go_Rush
  • galant2008
  • jiangtao088
  • hbhbhbhbhb1021
  • mingxuan3000
  • ttyp
  • hbhbhbhbhb1021
  • btbtd
  • Love_My
  • precipitant
  • myminimouse
  • royeleo
  • mldswt
  • qiuyi21
  • microjunjun
  • yousite1
  • huhh2004
  • fantiny
  • championmajian
  • mb459
  • ShinStone
  • GavinLv
  • handsomebird123
  • zzzsea
  • brothercat
  • w78z007
  • liuph3000
  • daluoboequalto
  • xuancaoer
  • gzty
  • championmajian
  • bamboo_2001
  • zoloao
  • afoskoo
  • li1229363
  • muxrwc
  • okitgo
  • nanfeng916
  • emilchan6k
  • woyingjie
  • squallqiu
  • shjohnson
  • FEB15
  • qqulijun

相关链接

  • Web开发类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
惹火投票。。火热进行中...
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo