在开发当中,我们经常要处理 url。而 url 上的 query string 是我们重点要处理的对象,完成一个 parseQueryString 函数。它接受一个 url 字符串作为参数,返回一个对象,这个对象包含 query string 上的键值对。例如:
parseQueryString('https://scriptoj.com/problems?offset=100&limit=10')
返回:
{ offset: '100', limit: '10'}
特殊情况说明:
如果出现 ?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}
答案
这道题本身不难,但是由于基础不扎实还是踩到了坑,首先数组、对象的拷贝都是浅拷贝,只是拷贝了名称引用,一处修改,将造成所有引用的变化。例如下面,对last的删除动作将引起KV的变化!
let KV=item.split('=')
let last=KV // 错误,对象赋值为浅拷贝
last.splice(0,1) // 删掉第一个值,splice的返回值为被删掉的值
必须使用 let last=[...KV]
或者 let last=KV.concat([])
,就可以实现对数组的保存。
对象也是同理:let last={...KV}
或者 let last=JSON.parse(JSON.stringify(KV))
注意不要使用 let last=Object.assign({},KV)
Object.assign只是对对象根属性进行了深拷贝,根属性中嵌套的子对象依旧是浅拷贝。
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
}
}
网友评论