когда ты видишьparseUrlКогда
Нам не нужно слишком заботиться о собеседовании, расслабьтесь и не терпите психологического давления, даже если оно насыщено рутиной, мы все равно легко с этим справимся.
Основная цель parseUrl — анализировать URL-адреса.Строка запроса
Тогда мы такжеНезависимо от тогокакой хеш пишется#Материал, стоящий за номером, исчез, только чтобы вернуться к?Строка запроса после числа находится здесь
Тысяча лет одним взглядом
Когда-то, когда вы видели такие строки'q=nba&src=home&fr=so', первая реакция, маленькая сцена, используйте функцию разделения, чтобы разделить ее, сначала разделить&, а затем разделить=, футляр вещь
Поскольку все это знают, продавать не буду, а начну играть.
Этот parseUrl очень распространен
Написание обычного parseUrl, особенно обычного, для нашего фронтенда проще простого.
function parseUrl(str) {
return str.split('&').reduce((obj, pair) => {
// 解构数组所对应的值
const [key, value] = pair.split('=');
// 将键值对写入obj
obj[key] = value;
return obj;
}, {});
}
// 测试用例1
let s1 = 'q=nba&src=home&fr=so';
console.log(parseUrl(s1)); // {q:'nba',src:'home',fr:'so'}
Но кто бы мог подумать, что когда ты трахаешься как тигр, ты на самом деле закапываешь маленькую скрытую опасность
Если тестовый пример'q=nba&src=home&fr=so&fe', будет небольшая проблема, пожалуйста, посмотрите на большой экран
function parseUrl(str) {
return str.split('&').reduce((obj, pair) => {
const [key, value] = pair.split('=');
obj[key] = value;
return obj;
}, {});
}
// 测试用例2
let s2 = 'q=nba&src=home&fr=so&fe';
console.log(parseUrl(s2)); // {q:'nba',src:'home',fr:'so',fe:undefined}
из-за тестового примераfeЗначение отсутствует, поэтому оно напрямую не определено, что вроде бы ни на что не влияет.
Однако, если с этой ситуацией можно справиться, мы не можем закрывать глаза, давайте модифицируем ее, это очень просто.
Вы должны управлять без ценности
function parseUrl(str) {
return str.split('&').reduce((obj, pair) => {
const [key, value] = pair.split('=');
++++++
// 没有value值的情况,就返回obj中已有的内容
if (!value) {
return obj;
}
++++++
obj[key] = value;
return obj;
}, {});
}
// 测试用例2
let s2 = 'q=nba&src=home&fr=so&fe';
console.log(parseUrl(s2)); // {q:'nba',src:'home',fr:'so'}
Небольшие скрытые опасности были легко решены нами, давайте рассмотрим другую ситуацию
Строка запроса URL может содержать такие символы'q=nba&fe[pro]=news&fe[pid]=result'
Согласно приведенному выше письму, это распечатывается так{q:'nba','fe[pro]':'news','fe[pid]':'result'}
На самом деле, с точки зрения знакомой нам системы знаний, очевидно, чтоfeНа самом делетип объекта, значит так не должно быть, по крайней мере так{q:'nba',fe:{pro:'news', pid:'result'}}
Итак, давайте проведем еще несколько исследований
слой за слоем в объект
Принцип не сложный, на самом деле, если мы встретим символ, который выглядит как тип объекта, мы будем рассматривать его как объект, после обработки первого слоя мы обработаем второй слой и так далее.
function parseUrl(str) {
return str.split('&').reduce((obj, pair) => {
const [key, value] = pair.split('=');
if (!value) {
return obj;
}
// obj[key] = value 废弃废弃废弃
// 深入到obj的内部去搞
deepObj(obj, key.split(/[\[\]]/g).filter(v => v), value);
return obj;
}, {});
}
// 深度设置对象
function deepObj(obj, keys, value) {
// 下面我们所有涉及注释部分,都用fe[pro]来说明一下
// fe[pro]被正则处理,匹配[和],以[或]分割出来的数组是这样的['fe', 'pro', '']
// 然后我们只取非空值部分,就用filter过滤了一下,得到['fe', 'pro']
console.log(keys); // ['fe', 'pro']
let i = 0;
for (; i < keys.length - 1; i++) {
let key = keys[i];
// key值为fe
if (!obj[key]) { // obj中没有fe
obj[key] = {}; // { fe: {} }
}
// 深入到obj的下一层
obj = obj[key]; // 引用fe这个对象{}
}
// 相当于在fe对象里加属性,fe:{pro: 'news'}
obj[keys[i]] = value;
}
// 测试用例3
let s3 = 'q=nba&fe[pro]=news&fe[pid]=result';
console.log(parseUrl(s3)); // {q:'nba',fe:{pro:'news', pid:'result'}}
Вышеприведенный код просто анализируется с помощью комментариев, надеюсь всем понятно
Далее мы продолжаем рассказывать о похожем объекте, который записывается в виде массива, и слушать ветер, чтобы увидеть этот вариант использования'q=nba&box[0]=one&box[1]=two'
Для синтаксического анализа этот способ записи должен возвращать следующий формат{q:'nba',box:['one', 'two']}
Итак, без лишних слов, давайте вернемся к deepObj, чтобы посмотреть, как с этим бороться.
Массивы должны выглядеть как вы
function parseUrl(str) {
...省略
}
function deepObj(obj, keys, value) {
let i = 0;
for (; i < keys.length - 1; i++) {
let key = keys[i];
if (!obj[key]) {
++++++
// 如果是数组的话,keys应该是这样的['box', '0']
// 所以来判断keys的i+1位置(就是索引为1),是不是数字就行
// 是数字的话就当做数组类型来处理即可了
if (keys[i + 1].match(/^\d+$/)) {
obj[key] = [];
} else {
obj[key] = {};
}
++++++
}
obj = obj[key]
}
obj[keys[i]] = value;
}
// 测试用例4
let s4 = 'q=nba&box[0]=one&box[1]=two';
console.log(parseUrl(s4)); // {q:'nba',box:['one', 'two']}
Декодировать процентное кодирование
Последний случай таков,'q=you%2Bme&name=jay%20chou', мы видим%число, то есть, например空格,+号Такие специальные символы кодируются
Итак, не паникуйте, поскольку он закодирован, мы можем использовать предоставленный метод декодирования, чтобы сделать это, этоdecodeURIComponent
Код также очень легко модифицировать.В функции deepObj до тех пор, покаobj[keys[i]] = valueизменить наobj[keys[i]] = decodeURIComponent(value)Вот и все
function parseUrl(str) {
...省略
}
function deepObj(obj, keys, value) {
...省略
obj[keys[i]] = decodeURIComponent(value);
}
// 测试用例5
let s5 = 'q=you%2Bme&name=jay%20chou';
console.log(parseUrl(s5)); // {q:'you+me',name:'jay chou'}
каждый показывает свои силы
На самом деле, благодаря четырем видам подпрограмм, описанным выше, многие люди смогли пройти тест, и я не ожидал, что небольшая операция по разбору строки запроса на самом деле скроет такие магические способности.
Это тоже должно заставить людей вздохнуть, мир JS всегда так широк и глубок, но мы не остановимся и продолжим усердно учиться.
Спасибо за просмотр, 886