在開(kāi)發(fā)當(dāng)中,我們經(jīng)常要處理 url。而 url 上的 query string 是我們重點(diǎn)要處理的對(duì)象,完成一個(gè) parseQueryString 函數(shù)。它接受一個(gè) url 字符串作為參數(shù),返回一個(gè)對(duì)象,這個(gè)對(duì)象包含 query string 上的鍵值對(duì)。例如:
parseQueryString('https://scriptoj.com/problems?offset=100&limit=10')
返回:
{ offset: '100', limit: '10'}
特殊情況說(shuō)明:
如果出現(xiàn) ?name=&age=12 則返回 { name: '', age: '12' },
如果 ?name&age=12 則返回 { name: null, age: '12' }
如果 ?name=jerry#nice 則返回 { name: jerry }
如果 ?page=all?cur=10 則返回 { page:all?cur=10}
答案
這道題本身不難,但是由于基礎(chǔ)不扎實(shí)還是踩到了坑,首先數(shù)組、對(duì)象的拷貝都是淺拷貝,只是拷貝了名稱引用,一處修改,將造成所有引用的變化。例如下面,對(duì)last的刪除動(dòng)作將引起KV的變化!
let KV=item.split('=')
let last=KV // 錯(cuò)誤,對(duì)象賦值為淺拷貝
last.splice(0,1) // 刪掉第一個(gè)值,splice的返回值為被刪掉的值
必須使用 let last=[...KV]
或者 let last=KV.concat([])
,就可以實(shí)現(xiàn)對(duì)數(shù)組的保存。
對(duì)象也是同理:let last={...KV}
或者 let last=JSON.parse(JSON.stringify(KV))
注意不要使用 let last=Object.assign({},KV)
Object.assign只是對(duì)對(duì)象根屬性進(jìn)行了深拷貝,根屬性中嵌套的子對(duì)象依舊是淺拷貝。
const parseQueryString = (url)=>{
let hashIdx=url.indexOf("#")
if(hashIdx!=-1){
url=url.substring(0,hashIdx)
}
let qIdx=url.indexOf("?")
let r={}
if(qIdx==-1){
return r
}else{
url=url.substr(qIdx+1)
url=url.split('&')
url.forEach((item,idx)=>{
let KV=item.split('=')
if(KV.length>2){
let last=[...KV]
last.splice(0,1)
KV[1]=last.join('=')
}
if(KV[1]===undefined){
r[KV[0]]=null
}else{
r[KV[0]]=KV[1]
}
});
return r
}
}