Строка escape в контексте eval с помощью JSON.stringify
Прежде всего: я знаю, что есть много вопросов, связанных с побегом, но я пока не нашел в целом рабочего ответа. Скажем, у меня есть эта простая игрушечная функция для демонстрации:
function f(somePOJO) {
var s = eval("'" + JSON.stringify(somePOJO) + "';"); // for demonstration only
return JSON.parse(s);
}
const clone = f({a: 1, b: "c"});
Учитывая литерал объекта, такой как {a: 1, b: "c"}(POJO), fдолжен возвращать его "клон". (Обратите внимание, что я на самом деле не использую этот подход для клонирования или подобного, и я знаю, что evalэто зло, а также то, что здесь он даже не нужен, это просто для демонстрации проблемы с побегом!)
Это работает нормально, но только до тех пор, пока значения POJO не содержат '. Теперь, конечно, я мог бы избежать JSON, используя что-то вроде JSON.stringify(somePOJO).replace(/'/g, "\\'"). Это работает, если значения POJO содержат ', но не содержат \\'. И это создает спираль бегства ...
Есть ли вообще решение этой проблемы?
Ответы
Функция escape для сохранения строки JSON путем ее оценки evalфункцией, компилятором JavaScript при некоторых обстоятельствах или самой JSON.parseфункцией JSON.stringify. Этот JSONметод успешно преобразовывает строковые значения, а не только типы данных объекта.
function f(somePOJO) {
var s = eval( JSON.stringify(JSON.stringify(somePOJO)) );
return JSON.parse(s);
}
const obj = {a: 1, b: "c", d: "back\\, forward/"}
const clone = f(obj);
console.log(obj);
console.log(clone);
Причина, по которой он не входит в escape/encodeURI/encodeURIComponentсемейство функций, заключается в том, что они предназначены для экранирования символов для включения в URL-адреса, тогда как в данном случае речь идет об экранировании символов, которые должны быть проанализированы парсером JavaScipt.
В большинстве случаев, особенно для синтаксического анализа текста JSON.parseJSON, повторное преобразование текста JSON в строку и его двойной синтаксический анализ просто не нужны.
В настоящее время представляет некоторый академический интерес, но до введения JSONв Javascript можно было преобразовать строку в строку, последовательно проверяя ее символы и обратную косую черту, избегая обратной косой черты, по крайней мере, один вид кавычек и управляющих кодов с экранированием Unicode - в опубликованном вопросе может отсутствовать часть о необходимости экранировать символы обратной косой черты, а также кавычки.