2019独角兽企业重金招聘Python工程师标准>>>
replace的第二个参数作为函数的一个例子:
var a = 'aaa bbb ccc';
var b=a.replace(/\b\w+\b/g, function(word){//\b:单词的边界,\w:字母数字和下划线,+:至少出现一次
console.log(arguments[0]+','+arguments[1]+','+arguments[2]+','+arguments[3]);
return word.substring(0,1).toUpperCase()+word.substring(1);
});
document.write (b);
输出结果为:
通过正则/\b\w+\b/g可以匹配出3个子字符串:aaa、bbb和ccc,如果replace的第二个参数是函数,那么匹配出的3个子表达式将分别作为那个匿名函数的第一个参数,在匿名函数内部我们可以对匹配出的子表达式做更多的处理,然后返回结果。这个例子中是将匹配出的子表达式进一步处理成首字母大写。
通过语句:
console.log(arguments[0]+','+arguments[1]+','+arguments[2]+','+arguments[3]);
我们发现匿名函数到了第四个参数时已经是undefined,好像只有3个参数。然而关于匿名函数的参数w3school上是这样解释的:
1、该函数的第一个参数是匹配模式的字符串。
2、接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数。
3、接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置。
4、最后一个参数是 stringObject 本身。
按照这种解释,匿名函数应该至少有4个参数,可是细看第二句话,发现它说的是可以有“ 0 个或多个这样的参数”,有0个,也就是没有。这个可有可无的参数返回的是“模式中的子表达式匹配的字符串”,如果模式中没有子表达式,自然也就没有这个参数了,而上面例子中正好没有子表达式:/\b\w+\b/g
如果我们把正则:/\b\w+\b/g修改为/\b(\w+)\b/g,增加一个子表达式,再观察上例中的js,就会发现它4个参数全部返回结果了:
题目我说“了不起的replace”,replace了不起在哪呢?
我们平时经常会用js做一些字符串的拼装,拼装一个html结构,然后方便js去动态处理一些页面结构,很复杂的时候我们会用一些专业的js模板,相当强大。有的时候是很简单的,我们会直接拼装,可是直接拼装如同鸡肋,可以不必为了一个小功能引入一个js插件,但是写起来又有点笨笨的,n多加号引号写起来繁琐且容易出错,感觉不是很先进,形如:
var str =+''+a+'
'
+''+b+''
+''+c+'
'
+''+d+''
+''+e+'
'
+''+f+''
如果利用replace的第二个参数可以作为函数的特性,我们可以这样处理一个js拼接应用:
function fn(str,o){
return str.replace(/\\?\{([^{}]+)\}/g,function(match,name){
return (o[name]===undefined)?'':o[name];
});
}
var data={val:'123',txt:'abc'};
var str='{txt}
{val}';
var str2 = fn(str,data);
console.log(str2);
如上例,我们只用把全部结构拷贝到单引号的str字符串中,把需要替换的地方用大括号括起来,写上和数据对象字段相对应的字段即可。
这样优势好像不明显?那再优化下:
如上例,我们可以把一段带结构的html字符串直接拷贝到一对script标签内,注意修改type属性,只要不是真正存在的语言类型即可。然后修改那段html里的需要js动态处理的字段,用大括号进行包装,这样既保证了模板字符串的可读性(有换行,可以基本保持html标签原有的结构),又保证了它的易用性(不比写很多引号、单引号、转义符、加号之类的)