我在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)范例来改进我的代码非常感兴趣。
答案 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。 :)