Как бы вы реорганизовали этот объектный цикл Javascript? - PullRequest
0 голосов
/ 09 июля 2019

Я написал эту базовую функциональность в ES5, которая работает для браузеров.Он должен выполнять итерацию по списку пар символ / кодирование и преобразовывать их через переданную строку / запрос.Я знаю, что, вероятно, есть более изящный способ написания этого архаичного стиля кода.Ребята, не возражаете ли вы уделить минуту тому, чтобы поделиться своей реализацией?

Я пишу Python уже год, и у меня нет опыта в ES7.

function encodeURLBreakers(query) {
    var URLBreakers = {
        '/': '%2F',
        '?': '%3F',
        '#': '%23'
    }; 
    for (var key in URLBreakers) {
        var reg = '/' + URLBreakers[key] + '/g';
        query.replace(key, reg);
    }   
    return query;
}

Что было бы хорошим способом для рефакторингаэто в многократно используемую функцию с использованием цикла типа карты над объектом Javascript.

Это все, что я пробовал, и это работает, но он использует старый синтаксис.Я очень заинтересован в изучении и использовании современных парадигм JS (ES7) для улучшения моего кода.

Ответы [ 3 ]

1 голос
/ 09 июля 2019

Игнорируя encodeURIComponent, я бы, вероятно, использовал функциональность обратного вызова replace:

function encodeURLBreakers(query) {
    const URLBreakers = {
        '/': '%2F',
        '\\?': '%3F',
        '#': '%23'
    };
    const regex = new RegExp(Object.keys(URLBreakers).join("|"), "g");
    return query.replace(regex, match => URLBreakers[match]);
}

Сделано в функцию многократного использования:

function makeReplacer(map) {
    const regex = new RegExp(Object.keys(map).join("|"), "g");
    return string => string.replace(regex, match => map[match]);
}

const encodeURLBreakers = makeReplacer({
    '/': '%2F',
    '\\?': '%3F',
    '#': '%23'
});

В этом трюке используются альтернативы регулярному выражению, чтобы вообще избежать зацикливания.Если бы вам абсолютно необходимо было сделать это итеративно (например, потому что порядок имел значение, а некоторые выражения соответствовали результатам предыдущих замен), я бы выбрал reduce:

function encodeURLBreakers(string) {
    return [
         [/\//g, '%2F'],
         [/?/g, '%3F'],
         [/#/g, '%23'],
    ].reduce(
         (str, [regex, replacement]) => str.replace(regex, replacement),
         string
    );
}
0 голосов
/ 09 июля 2019

Если вы конвертируете отдельные символы, Array.from - это способ создать массив из преобразования каждой кодовой точки строки (или каждого элемента любой итерируемой в целом):

const substitute = map => c => {
    const t = map.get(c);
    return t === undefined ? c : t;
};

const translateString = map => text =>
    Array.from(text, substitute(map)).join('');

const encodeURLBreakers = translateString(new Map([
    ['/', '%2F'],
    ['?', '%3F'],
    ['#', '%23'],
]));


console.log(encodeURLBreakers('hello? world?'));

Почти все здесь - ES6, так что это настолько ES6y, насколько я могу это сделать. :)

0 голосов
/ 09 июля 2019

Очень похоже на ответ Берги, только с немного другим вкусом, это:

const URLBreakers = {
    '/': '%2F',
    '?': '%3F',
    '#': '%23'
}

const changes = Object .entries (URLBreakers) .map 
  ( ([unsafe, safe]) => [new RegExp (`\\${unsafe}`, 'g'), safe]
  )

const encodeURLBreakers = (str) => 
  changes .reduce
    ( (s, [regex, safe]) => s .replace (regex, safe)
    , str
    )

console .log (
  encodeURLBreakers ('aaa/bbb?#ccc') //~> 'aaa%2Fbbb%3F%23ccc'
)

Если вы не хотите использовать это как модуль и хотите инкапсулировать хелперы, просто оберните все в IIFE, возвращая финальную функцию и присваивая результаты encodeURLBreakers.

Обратите внимание, что мы избегаем символов, когда создаем из них регулярные выражения. Например, '?' не является допустимым телом регулярного выражения. Это не так универсально, как хотелось бы. См. Комментарии к ответу Берги для более полного ответа на этот вопрос.

Наконец, обратите внимание, что один из символов, который вам действительно необходимо экранировать в истинных строках запроса, - %. Если вам действительно нужно это сделать, этого будет недостаточно, поскольку вы получите бесконечный регресс, поскольку ваш результат добавил больше % s; вам придется использовать что-то более похожее на первую версию Берги, возможно, с выходом регулярного выражения, которое я предложил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...