我正在考虑对文本字符串中的${something}
变量进行独立解析,对它们执行eval()
并在结果字符串中替换。
是否有任何特定的ES6模板变量需要注意?是什么使它们的行为与标准eval()
的行为不同?
示例:
var value = // a string, number, object,... anything;
var a = `${value}`; // use ES6 template string
var b = '${value}'.replace('${value}', eval(value));
a
和b
的结果可以与哪些方式和原因不同?
答案 0 :(得分:1)
考虑这个例子:
var a = 'test';
var str1 = `${a} ${a} ${a}`; //test test test
var str2 = '${a} ${a} ${a}'.replace('${a}', a); //test ${a} ${a}
另外,请考虑以下事项:
var str1 = `${Math.random()} ${Math.random()}` //0.7818185299239435 0.8991473634359528
var str2 = '${Math.random()} ${Math.random()}'.replace('${Math.random()}', Math.random()); //0.9327690218686401 ${Math.random()}
请记住,${...}
中的任何内容都将被评估为代码,并且其结果将用于字符串中。
你可以争论使用正则表达式和什么不是,但也要考虑这个:
var str1 = `${5+`${Math.random()}`}`; //50.11300474012906858
是的,模板字符串可以嵌套!如何替换它来处理它?</ p>
所以,在一个小清单中:
这些是差异。
您可能会询问安全问题。嗯,它比var a = eval('str')
或var a = Function('return str')()
没有或多或少。
但是,有一个转折:它将在返回的值上运行.toString()
。最小的可验证示例如下:
alert(`${{}}`) // calling alert`${{}}` will only show ","
如果你以某种方式设法使用你的方法,用这种假设的方式:
alert('${R}'.replace( /\$\{(\w[\w\d]*)\}/g, (_, v) => eval(v)));
你是相对安全的*! 相对而言
然而,非常小心eval
与window.eval
!!!
以下是一个例子:
window.R = {
toString: _ => 'evil'
};
(window => {
var R = 'nice';
//Using evil! erm ... eval()
alert('${R}'.replace( /\$\{(\w[\w\d]*)\}/g, (_, v) => eval(v)));
//Using MOAR window.evil! erm ... window.eval()
alert('${R}'.replace( /\$\{(\w[\w\d]*)\}/g, (_, v) => window.eval(v)));
//String templates
alert(`${R}`);
})(window)
它应该表现出好看,邪恶,美好&#34;。这意味着window.eval
在全局范围内运行,而eval
在本地范围上运行。除了eval()
已经存在的问题之外,这是我看到的唯一安全问题。
简而言之,您的方法与使用字符串模板一样安全。