加固javascript基礎知識目的是為以後研究jQuery源碼做好鋪墊。
我最近查閱javascript資料,發現瞭一個函數:
function format(s) { var args = arguments; var pattern = new RegExp("%([1-" + arguments.length + "])","g"); return String(s).replace(pattern,function(word,index){ return args[index]; }); } // test window.onload = alert(format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear")); //And the papers want to know whose shirt you wear
這種功能的函數,在shell或java都似曾見過,但是在javascript函數實現的方法很新穎。新穎的地方就是在:
return String(s).replace(pattern,function(word,index){ return args[index]; });
但是這裡String類的replace的用法和我平時用的很不一樣,我以前寫過一個這樣的replace的函數:
function myReplace(s) { return String(s).replace(/CJ[0-9]{2}/g,function(word){ return word = 'CJJK00'; }); } //window.onload = alert(myReplace('CJ9080,CJ8976,CJ12919,CJ8765'));//CJJK0080,CJJK0076,CJJK00919,CJJK0065
我在使用replace時候,如果第二個參數是function我一般都隻用到第一個參數,基本沒有思考它的第二個,第三個或者更多的參數,現在看到有人使用瞭第二個參數,就很想探求下replace第二個參數使用到瞭function時候,裡面參數到底有多少個,每個的含義到底如何?
下面是我改寫瞭我自己寫的替換函數:
function myReplaceFtn(s) { return String(s).replace(/CJ[0-9]{2}/g,function(word,index){ return word = 'CJJK00@' + index + "@"; }); } //window.onload = alert(myReplaceFtn('CJ9080,CJ8976,CJ12919,CJ8765'));//CJJK00@0@80,CJJK00@7@76,CJJK00@14@919,CJJK00@22@65
本來我以為,函數format裡的function(word,index),我認為應該是正則表達式所匹配字符串的索引(%1的索引為1,%2的索引為2,%3的索引為3),而我寫的函數裡面第二個參數index不是被匹配到字符串的索引,而是被匹配到的字符在原字符串的位置。下面我做瞭這樣的測試:
function format(s) { var args = arguments; var pattern = new RegExp("%([1-" + arguments.length + "])","g"); return String(s).replace(pattern,function(word,index){ alert("arguments.length:" + arguments.length);//4 return args[index]; }); } function myReplaceFtn(s) { return String(s).replace(/CJ[0-9]{2}/g,function(word,index){ alert("arguments.length:" + arguments.length);//3 return word = 'CJJK00@' + index + "@"; }); }
函數format裡面function(word,index)的參數有4個,而函數myReplaceFtn(s)裡面function(word,index)的參數有3個。為什麼會有這樣的不同?我做瞭如下測試:
//以下程序在firefox裡面運行 function newformat(s) { var args = arguments; var pattern = new RegExp("%([1-" + arguments.length + "])","g"); return String(s).replace(pattern,function(word,index){ console.log("arguments.length:" + arguments.length); for (var i = 0,j = arguments.length;i<j;i++) { console.log("標示newformat" + i + ":" + arguments[i]); } return args[index]; }); } function newmyReplace(s) { return String(s).replace(/CJ[0-9]{2}/g,function(word){ console.log("arguments.length:" + arguments.length); for (var i = 0,j = arguments.length;i<j;i++) { console.log("標示newmyReplace" + i + ":" + arguments[i]); } return word = 'CJJK00'; }); } 結果: arguments.length:4 標示newformat0:%1 標示newformat1:1 標示newformat2:8 標示newformat3:And the %1 want to know whose %2 you %3 arguments.length:4 標示newformat0:%2 標示newformat1:2 標示newformat2:30 標示newformat3:And the %1 want to know whose %2 you %3 arguments.length:4 標示newformat0:%3 標示newformat1:3 標示newformat2:37 標示newformat3:And the %1 want to know whose %2 you %3 arguments.length:3 標示newmyReplace0:CJ90 標示newmyReplace1:0 標示newmyReplace2:CJ9080,CJ8976,CJ12919,CJ8765 arguments.length:3 標示newmyReplace0:CJ89 標示newmyReplace1:7 標示newmyReplace2:CJ9080,CJ8976,CJ12919,CJ8765 arguments.length:3 標示newmyReplace0:CJ12 標示newmyReplace1:14 標示newmyReplace2:CJ9080,CJ8976,CJ12919,CJ8765 arguments.length:3 標示newmyReplace0:CJ87 標示newmyReplace1:22 標示newmyReplace2:CJ9080,CJ8976,CJ12919,CJ8765
對於回調函數裡的arguments值現在比較清晰瞭,arguments個數的不同應該和我們寫的正則表達式有關系,不管怎樣,第一個參數是匹配到的字符串,最後一個是原字符串,倒數第二個參數是匹配到的字符串的在原字符串索引的起始位,像format裡的第二個參數index根據情況而定瞭,我自己寫的newmyReplace裡沒有這個參數,format的index參數是%[1-4],裡面的1-4,不過還是寫個方法確定下:
function charFormat(s) { var pattern = new RegExp("%([a-d])","g"); return String(s).replace(pattern,function(word,index){ switch(index) { case 'a': return 'thisisA'; case 'b': return 'thisisB'; case 'c': return 'thisisC'; case 'd': return 'thisisD'; default: return 'thisisNULL'; } }); } window.onload = console.log(charFormat("And the %a want to know whose %d you %b", "papers", "shirt", "wear"));
//And the thisisA want to know whose thisisD you thisisB
由此可見String的replace是相當的強大,不過本人正則表達式功力還不夠,不知道還有什麼別的特別的正則表達式會產生什麼不同的結果。另外不知道誰有javascript裡面String類replace原始寫法,希望能貢獻出來,我想好好研究下。
作者“sharpxiajun”