wingmeng / front-end-quiz

前端小测试答题收集
0 stars 0 forks source link

JS基础测试35期:URL传值操作 #22

Open wingmeng opened 5 years ago

wingmeng commented 5 years ago

题目:

image

我的回答:

const object1 = {
  userid: 123,
  username: '王二',
  tel: '13208033621'
};

第 1 题:

一句话:两者都会对 URL 中的特殊字符进行编码,区别是两者编码的字符范围不一样,前者不会对属于 URI 的特殊字符进行编码,而后者会。

第 2 题:

Object.keys(object1)
  .map(key => `${key}=${encodeURIComponent(object1[key])}`)  // 转码
  .join('&');

第 3 题:

location.search;

第 4、5 题:

2019-07-25 修改:调整了函数和形参命名,使之更加语义化;增加了测试用例

// zxx: 有bug
function getQueryObj(queryStr = '') {
  // 移除前面的 ? 号(如有)
  queryStr = queryStr.indexOf('?') === 0 ? queryStr.substr(1) : queryStr;
  if (!queryStr) return {};

  return queryStr.split('&')
    .map(s => s.split('='))  // 拆解 key 和 value
    .reduce((obj, [key, value]) => {
      value = value ? decodeURIComponent(value) : '';  // 解码

      if (key in obj) {
        Array.isArray(obj[key]) ? obj[key].push(value) : obj[key] = [obj[key], value];
      } else {
        obj[key] = value;
      }

      return obj;
    }, {});
}

getQueryObj 测试用例:

getQueryObj();  // 参数为空

// 一般情况
getQueryObj('userid=123&username=%E7%8E%8B%E4%BA%8C&tel=13208033621');

// 空值(username 值为空)
getQueryObj('userid=123&username=&tel=13208033621');

// 多个重复的键名(tel、favorite)
getQueryObj('?userid=123&tel=13208033621&username=%E7%8E%8B%E4%BA%8C&favorite=rap&favorite=Hip%20hop&favorite=basketball&tel=15888888888&tel=18099999999');
wingmeng commented 5 years ago

自我评分:一般

优秀、良好、一般、差劲

不足之处:

  1. 未充分考虑特殊 url 的边界情况,如 from=user.html?id=1
  2. 基于 .split('=') 实现参数获取的方式健壮性不足。

学习收获:

  1. 专门用于 URL 字符串查询的 API:URLSearchParams
wingmeng commented 5 years ago

最佳实践:

// 第 4、5 题
const queryStr = '?userid=123&tel=13208033621&username=王二&favorite=rap&favorite=Hip%20hop&favorite=basketball&tel=15888888888&tel=18099999999'
const urlObj = new URLSearchParams(queryStr);
const result = {};

for (let [key, value] of urlObj.entries()) {
  if (key in result) {
    Array.isArray(result[key]) ?
      result[key].push(value) :
      result[key] = [result[key], value];
  } else {
    result[key] = value
  }
}

console.log(result)