您将如何重构此Javascript对象循环?

时间:2019-07-09 19:38:05

标签: javascript object optimization

我在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 个答案:

答案 0 :(得分:1)

忽略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
    );
}

答案 1 :(得分:0)

与Bergi的答案非常相关,只是口味略有不同,是这样的:

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

请注意,当我们从中创建正则表达式时,我们会对这些字符进行转义。例如,'?'不是正则表达式的有效主体。这不是我们想要的通用。有关更完整的答案,请参见Bergi答案的评论。

最后,请注意,您真正需要在真实查询字符串中转义的字符之一是%。如果您确实需要这样做,那将是不够的,因为您的结果增加了%,因此您遇到了无限次的回归;您可能需要使用更像Bergi的第一个版本的东西,也许我建议使用正则表达式转义。

答案 2 :(得分:0)

如果您要转换单个字符,则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。 :)