js过程中常常会用到字符串拼接,很多时候这些拼接又长又硬,而js又没有提供像其他语言一样的字符串格式化方式,于是我们只好DIY了。
一般来说,我们需要实现如下两种方式的格式化:
"{0},{1},hehe"
.format(
"hello"
,
"world"
)
"数学={数学},语文={语文},hou"
.format({
"数学"
:100,
"语文"
:95})
|
第一种是常规的格式化方法 ,很多语言中常见。第二种就不那么常见了 ,但是在Js中却很重要,特别是在ajax交互式后我们返回一堆的json数据。当然有很多人都写过兼容的format写法,但我们今天要尝试另外一些方法。
仔细观察上面的2中格式话方法,我们发现方法签名相同,但参数有所不同。不正好用到JavaScript函数重载模拟一文中的方法重载么?那么就应该有如下的实现:
sm.Overload(
"format"
,String.prototype,{
"string,string,string...."
:
function
(a,b,c,....){
//pass
},
"object"
:
function
(param){
//pass
}
});
|
写完之后发现有点纠结,我们的Overload方法是根据fn_obj对象的键值(如上面代码的"string,string,string....")来给定相对的实现的,但是string的个数确实不确定的,我们无法用它来当一个确定的键值。
怎么办呢?
很容易! 这一堆的string不就代表一个string集合么?用一个Array表示就行了啊。so...
sm.Overload(
"format"
,String.prototype,{
"array"
:
function
(params){
//params is a array
},
"object"
:
function
(param){
//param is a object
}
});
|
剩下的代码就很好写了:
sm.Overload(
"format"
,String.prototype,{
"array"
:
function
(params){
var
reg = /{(\d+)}/gm;
return
this
.replace(reg,
function
(match,name){
return
params[~~name];
});
},
"object"
:
function
(param){
var
reg = /{([^{}]+)}/gm;
return
this
.replace(reg,
function
(match,name){
return
param[name];
});
}
});
|
调用之:
"{0},{1},hehe"
.format([
"hello"
,
"world"
]);
//hello,world,hehe
"数学={数学},语文={语文},hou"
.format({
"数学"
:100,
"语文"
:95});
//数学=100,语文=95,hou
|
对函数签名相同参数不同的函数进行方法重载好处显而易见,每一中情况你都可以针对行的写出新的函数,而不是用一大堆的If,else。如果再有其他形式的格式化方式,你只需要用sm.Overload对String.prototype.format进行扩展即可,而不是去一个all方法里添加If。