字符串连接类(Javascript)

Get latest version 

根据12楼,改进下,支持连写:

 1 /*
 2  * @author: uedsky
 3  * @version: 1.1
 4  */
 5 
 6 /**
 7  * @class String concat
 8  * @return {StrBuf/String}
 9  * @constructor
10  * eg:
11     var buf = new StrBuf("contructor str\n");
12     buf.push("hello,")
13     .push("Today is {0}, {1}", "Monday", "March 28th")
14     .push("${name} is a good ${category} company", {name: "Google", category: "Intenet"});
15     document.write(buf);// auto call toString method
16     console.log(buf);
17     console.log(StrBuf("static {0} method", "invoke"));
18  */
19 var StrBuf = function(s) {
20     this.data = [];
21     if(s) {
22         var args = arguments, buf;
23         if(this instanceof StrBuf) {
24             this.push.apply(this, args);
25         }else {// static invoke
26             buf = new StrBuf();
27             return buf.push.apply(buf, args).toString();
28         }
29     }
30 };
31 StrBuf.prototype = {
32     // add String to the instance
33     push: function(s, j) {
34         var args = arguments;
35         if(args.length < 2) {
36             this.data.push(s || "");
37         }else if(typeof j == 'object'{
38             this.data.push(s.replace(/\$\{([\w.]+)\}/gfunction($, $1) {
39                 return ($1 in j) ? j[$1] : $;
40             }));
41         }else {
42             this.data.push(s.replace(/\{(\d+)\}/gfunction($, $1) {
43                 return args[+$1 + 1];
44             }));
45         }
46         return this;
47     },
48     toString: function() {
49         return this.data.join("");
50     }
51 };

 

最近在看一同事写的代码时,有一个字符串用了一堆“+”号,看了半天没明天到底会输出什么样的内容,

就想到用字符串连接的类,把以前的方法写成了类的方式,方便调用 ,

支持实例调用 和静态调用

参数可以是单独的字符串,或者json的格式,或者类似参数数组的方式,见下面示例 

 /*

 * @author: uedsky
 * @version: 1.0
 */

/**
 * @class String concat
 * @return {StrBuf/String}
 * @constructor
 
*/
var StrBuf = function(s) {
    
this.data = [];
    
if(s) {
        
var args = arguments, buf;
        
if(this instanceof StrBuf){
            
this.push.apply(this, args);
        }
else{// static invoke
            buf = new StrBuf();
            buf.push.apply(buf, args);
            
return buf.toString();
        }
    }
};
StrBuf.prototype 
= {
    
// add String to the instance
    push: function(s, j){
        
var args = arguments;
        
if(args.length < 2) {
            
this.data.push(s || "");
        }
else if(typeof j == 'object'){
            
this.data.push(s.replace(/\$\{([\w.]+)}/g, function($, $1){
                
return ($1 in j) ? j[$1] : $;
            }));
        }
else {
            
this.data.push(s.replace(/\{(\d+)}/g, function($, $1){
                
return args[+$1 + 1];
            }));
        }
    },
    toString: 
function(){
        
return this.data.join("");
    }
};
 
调用 示例如下:

      var buf = new StrBuf("contructor str\n");

    buf.push("hello,");
    buf.push(
"Today is {0}, {1}""Monday""March 28th");

    buf.push(
"${name} is a good ${category} company", {name: "Google", category: "Intenet"});
    document.write(buf);
// auto call toString method
    console.log(buf);
    console.log(StrBuf(
"static {0} method""invoke"));

If you could provide any suggestions or comments for this article, it is always welcome.

posted @ 2011-03-28 09:06 sohighthesky 阅读(1845) 评论(14) 编辑 收藏

 回复 引用 查看   
#1楼 2011-03-28 09:44 冰品羽扇      
做为脚本语言,未免小题大作了点,用数组来push性能也不可能得到明显提升。阅读角度来来看, "hello,"+name+"Today is"绝对比哑参数易读些吧
buf.push("hello,");
buf.push("Today is {0}, {1}", "Monday", "March 28th");
勤思考还是支持一下:)

 回复 引用 查看   
#2楼 2011-03-28 09:49 Rainr      
缺失非常不错..实用性很强。支持一下!
 回复 引用 查看   
#3楼[楼主] 2011-03-28 09:51 sohighthesky      
@冰品羽扇
所以要尽量使用json方式啊,
你觉得下面这句话你要多长时间能看明白到底结果想输出的啥?
html.push("<li>"+(i+1)+" . "+this.start_date+" "+this.start_time+" _ "+this.end_time+"<br>"+this.name+"计划</li>"

 回复 引用 查看   
#4楼 2011-03-28 10:08 early      
支持一下
 回复 引用 查看   
#5楼 2011-03-28 11:12 Kevan      
支持,不错的!
 回复 引用 查看   
#6楼[楼主] 2011-03-28 11:13 sohighthesky      
@Rainr
@early
@Kevan
谢谢支持

 回复 引用 查看   
#7楼 2011-03-28 11:30 colder      
支持楼主的方法!很好!!
 回复 引用 查看   
#8楼 2011-03-28 13:30 medns      
引用sohighthesky:
@冰品羽扇
所以要尽量使用json方式啊,
你觉得下面这句话你要多长时间能看明白到底结果想输出的啥?
html.push("<li>"+(i+1)+" . "+this.start_date+" "+this.start_time+" _ "+this.end_time+"<br>"+this.name+"计划</li>"


这个我一般这么写,'<li>{0}.{1} {2}_{3}<br>{4}计划</li>'.replace('{0}',...)这样的类似于C# String.Format的写法,简单好看又方便,可以用正则表达式替换,或者直接replace

 回复 引用 查看   
#9楼 2011-03-28 14:57 谷中宝      
必须得支持一下~
 回复 引用 查看   
#10楼 2011-03-28 17:02 木子博客      
你这种方式只适合IE6/IE7,其它的浏览器下[].join()连接字符串性能是最慢的(除了string.concat更慢)。
IE8以上的版本对字符串的+=有做性能优化,FF对硬字符串在编译期也有做优化。还是要区分浏览器会好一点。

 回复 引用 查看   
#11楼[楼主] 2011-03-28 17:06 sohighthesky      
@木子博客
感觉不是所有的时候都需要考虑性能,如果都考虑性能的话就不会有上面的方法了,本来如果考虑性能直接用字符串相加,而不是现在用正则替换了,
像别的语言的,如.net的format或者StringBuild.appendFormat一样会性能低很多

 回复 引用 查看   
#12楼 2011-03-28 17:28 阿K&LiveCai      
现在用的一个字符串拼接的拓展,在codeproject看到的。分享出来 给大家讨论讨论。。呵呵

var sb = new StringBuilder("StringBuilder");
sb.appendFormat("参数:{0}","cnblogs.com");
alert(sb.toString(););


	StringBuilder.prototype.CompositeFormattingRegExp = 
             new RegExp(/{\d+}|{\d+:[^\r\n{}]+}/g);
	StringBuilder.prototype.appendFormat = function() { 
	var Result = arguments[0]; 
	var RegExpResult = null; 
	while ((RegExpResult = CompositeFormattingRegExp.exec(Result)) != null) { 
		RegExpResult = RegExpResult.toString(); 
		var ColonsPosition = RegExpResult.indexOf(":"); 
		var paramIndex = -1; 
		var paramFormat = ''; 

		if (ColonsPosition != -1) { 
			paramIndex = new Number(RegExpResult.substr(
                               1, ColonsPosition - 1)); 
			paramFormat = RegExpResult.substr(ColonsPosition + 1,
                               RegExpResult.length - 2 - ColonsPosition); 
		} 
		else { 
			paramIndex = new Number(RegExpResult.substr(1,
                               RegExpResult.length - 2)); 
		} 
		paramIndex++;
		var Replacement = (
                      ColonsPosition != -1) ? arguments[paramIndex].toString(paramFormat) :
                      arguments[paramIndex].toString(); 
		Result = Result.replace(RegExpResult, Replacement); 
		CompositeFormattingRegExp.lastIndex += Replacement.length -
                      RegExpResult.length; 
	};
	this.append(Result); 
};



原文地址:Composite Formatting with a JavaScript StringBuilder Implementation

 回复 引用 查看   
#13楼[楼主] 2011-03-28 22:03 sohighthesky      
@阿K&LiveCai
不错,
改了下,chainability, 不过其它的感觉没必要,货币之类的用的少,clear还不如支持去操作data属性

 回复 引用 查看   
#14楼 2011-03-29 09:41 E猫      
性能太差了。还不如+=的性能好。
我做过测试,10000个字串相连,+=的性能比你这个快10倍。