JavaScript 讀 URL 參數改進版

此前發表的那一版確實能不用循環,但是總用正則表達式的替換,不一定比用循環提高性能,而且把程序搞得有些太複雜了。從《JavaScript權威指南》上學到的範例如下,

/* 《JavaScript權威指南》介紹的更簡潔的取 URL 參數的方法,不用正則表達式,用一次循環。一次性返回一個對象的好處是只需要調用一次此函數,參數和值對可以存在一個對象裏,以後再取其它參數的值就不用再調用此函數了,只要取對象的屬性就行了。
 * 用法:
 * var args = getArgs( );  // 從 URL 解析出參數
 * var q = args.q || "";  // 如果定義了某參數,則使用其值,否則給它一個默認值
 * var n = args.n ? parseInt(args.n) : 10;
 */
var getArgs = function ()
{
    var args = new Object( );  //聲明一個空對象
    var query = window.location.search.substring(1);     // 取查詢字符串,如從 http://www.snowpeak.org/testjs.htm?a1=v1&a2=&a3=v3#anchor 中截出 a1=v1&a2=&a3=v3。
    var pairs = query.split("&");                 // 以 & 符分開成數組
    for(var i = 0; i < pairs.length; i++) {
        var pos = pairs[i].indexOf('=');          // 查找 "name=value" 對
        if (pos == -1) continue;                  // 若不成對,則跳出循環繼續下一對
        var argname = pairs[i].substring(0,pos);  // 取參數名
        var value = pairs[i].substring(pos+1);    // 取參數值
        value = decodeURIComponent(value);        // 若需要,則解碼
        args[argname] = value;                    // 存成對象的一個屬性
    }
    return args;                                  // 返回此對象
}

它的突出優點就是程序只用執行一次提取操作,以後再重複取參數值,都不用再執行程序了。取 URL 參數還是這樣比較簡便易行,又好理解。

下面是我此前發表的“不用循環”但“有些太複雜”的版本:
//不用循環純用正則實現從 URL 中取參數的值。取代循環的核心技術是字符串的 replace() 方法可以用函數作第二參數,按用戶定義的方式去替換。
//若有此參數名但無值,則返回空字符串;若無此參數名,返回 undefined。
var getArg = function(argname)
{
 var str = location.href;
 var submatch;
 //先從 URL 中取出問號和井口與之間的查詢字符串,如從 http://www.snowpeak.org/testjs.htm?a1=v1&a2=&a3=v3#anchor 中截出 a1=v1&a2=&a3=v3。
 //問號是模式的特殊字符,所以要寫成 /?;井號可有可無,所以模式結尾是 #?
 if (submatch = str.match(//?([^#]*)#?/))
 {
  //取到捕捉的子匹配形如 a1=v1&a2=&a3=v3,在前面加個 & 做成規則的 &a1=v1&a2=&a3=v3 便於下一步替換
  var argstr = '&'+submatch[1];
  //做個替換用的函數,把找到的每組形如 &a1=v1 替換成 a1:"v1", 這樣的對象定義用的屬性聲明
  var returnPattern = function(str)
  {
   //$1 和 $2 代表捕捉到的第1個和第2個子匹配,必須用在字符串裏
   return str.replace(/&([^=]+)=([^&]*)/, '$1:"$2",');
  }
  //執行一個全局的正則替換,第二參數就是剛纔定義的替換函數,把 a1=v1&a2=&a3=v3 替換成 a1:"v1",a2:"",a3:"v3",
  argstr = argstr.replace(/&([^=]+)=([^&]*)/g, returnPattern);
  //最後再執行一個對象的聲明,需要形如 var retvalue = {a1:"v1",a2:"",a3:"v3"}; 的對象聲明,而剛纔替換完的字符串結尾還有個逗號,把結尾的逗號用 substr 截掉即可
  eval('var retvalue = {'+argstr.substr(0, argstr.length-1)+'};');
  //現在就得到了一個對象,URL 中每個參數名是其屬性名,參數值是對應的屬性值
  return retvalue[argname];
 }
}

//測試
document.write('a1='+getArg('a1')+', a2='+getArg('a2')+', a3='+getArg('a3'));

發佈了52 篇原創文章 · 獲贊 7 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章