ES6模板语句与eval()

时间:2016-02-03 16:52:28

标签: javascript node.js

我正在考虑对文本字符串中的${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));

ab的结果可以与哪些方式和原因不同?

1 个答案:

答案 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)));

你是相对安全的*! 相对而言

然而,非常小心evalwindow.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()已经存在的问题之外,这是我看到的唯一安全问题。

简而言之,您的方法与使用字符串模板一样安全。