使用Eval是个好主意吗?

时间:2018-01-22 12:00:11

标签: javascript reactjs ecmascript-6

我遇到的情况是,我必须动态object来自array object来自keys api的{​​{1}}。我使用eval来实现这种方法。

class App extends React.Component {

  constructor() {
    super();
    this.state = {
      title: 'Developers',
      descp: 'They are just amazing! JK',
      names: ['title', 'descp']     
    }
  }

  getVal(objKey) {
    let { title, descp } = this.state;
    return eval(objKey);
  }

  render() {
  let {names} = this.state;
    return (
      <div>
        <h2>{this.getVal(names[0])}</h2>
        <div>{this.getVal(names[1])}</div>
      </div>
    )
  }

}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

以上代码正常运行。

我后来发现的另一种方法:

render() {
  let {names} = this.state;
    return (
      <div>
        <h2>{this.state[names[0]]}</h2>
        <div>{this.state[names[1]]}</div>
      </div>
    )
  }

输出相同的结果。但我的问题是,如果我使用eval以下情况,这样做是否是一个好方法?

2 个答案:

答案 0 :(得分:1)

Eval应该避免,因为它可能非常危险。您可以通过括号表示法访问属性,安全地替换eval来电。

getVal(objKey) {
    if(this.state.hasOwnProperty(objKey)){
        return this.state[objKey];
    } else {
        // handle missing property
    }
}

答案 1 :(得分:-1)

通常会避免使用

Eval,因为它允许客户端在代码中插入和评估自己的表达式。

话虽如此,JavaScript作为客户端语言已经允许完全访问用户,因此没有充分的理由不使用它。

只要用户只能搞乱他们自己的会话,我就不用担心了。无论如何应该在服务器端处理安全性:小心但不要忽略Eval

编辑1 - 保护评估

评论指出了一些问题,主要是绩效/优化影响,this answer深入解释。基本上,既然它是即时编译的,那么在性能方面你就不会失去那么多。

关于用例的示例,这里是一个模板示例,我也使用了有争议的with语句:

&#13;
&#13;
var Template = /** @class */ (function () {
    function Template(html) {
        this.html = html;
    }
    Template.prototype.apply = function (params, returnDOMObject) {
        if (params === void 0) { params = {}; }
        if (returnDOMObject === void 0) { returnDOMObject = false; }
        with (params) {
            var html = eval('`' + this.html.replace(Template.regexes.encapsulated, function (n) {
                return n
                    .replace(Template.regexes.start, '${')
                    .replace(Template.regexes.end, '}');
            }) + '`');
        }
        if (returnDOMObject) {
            return document.createRange().createContextualFragment(html);
        }
        return html;
    };
    Template.regexes = {
        encapsulated: new RegExp('{{.*?}}', 'igm'),
        start: new RegExp('\{{2,}', 'igm'),
        end: new RegExp('\}{2,}', 'igm')
    };
    return Template;
}());
//TEST
var persons = [
    { name: "Peter", age: 25 },
    { name: "Ole", age: 55 },
];
var templates = [];
var container = document.body.appendChild(document.createElement("div"));
var leftBox = container.appendChild(document.createElement("div"));
var rightBox = container.appendChild(document.createElement("div"));
leftBox.style.width = rightBox.style.width = "50%";
leftBox.style.height = rightBox.style.height = "500px";
leftBox.style.cssFloat = rightBox.style.cssFloat = "left";
var leftList = leftBox.appendChild(document.createElement("select"));
leftBox.appendChild(document.createElement("br"));
var leftText = leftBox.appendChild(document.createElement("textarea"));
leftText.style.width = "100%";
leftText.style.resize = "vertical";
var rightOutput = rightBox.appendChild(document.createElement("div"));
function updateLists() {
    leftList.innerHTML = '';
    for (var i = 0; i < templates.length; i++) {
        var template = templates[i];
        var option = document.createElement("option");
        option.value = option.innerHTML = template.name;
        leftList.appendChild(option);
    }
}
var h1Template = new Template("<h1>{{name}}</h1>");
var h2Template = new Template("<h2>{{age}} is no age!</h2>");
var pTemplate = new Template("<p>{{name}} may be {{age}}, but is still going strong!</p>\n<p>(When he's {{age*2}} though...)</p>");
var personTemplate = new Template("<p>\n{{ h1Template.apply(params) }}\n{{ h2Template.apply(params) }}\n{{ pTemplate.apply(params) }}\n</p>");
templates.push({ name: "personTemplate", template: personTemplate });
templates.push({ name: "h1Template", template: h1Template });
templates.push({ name: "h2Template", template: h2Template });
templates.push({ name: "pTemplate", template: pTemplate });
function updateOutput() {
    rightOutput.innerHTML = '';
    for (var pi = 0; pi < persons.length; pi++) {
        var person = persons[pi];
        rightOutput.appendChild(personTemplate.apply(person, true));
    }
}
function leftTextChange() {
    templates.find(function (val) { return val.name === leftList.value; }).template.html = leftText.value;
    updateOutput();
}
function leftListChange() {
    leftText.value = templates.find(function (val) { return val.name === leftList.value; }).template.html;
}
updateLists();
leftList.onchange = leftList.onkeyup = leftListChange;
leftText.onchange = leftText.onkeyup = leftTextChange;
leftListChange();
updateOutput();
&#13;
&#13;
&#13;

此处用户输入文本正在实时解释,而用户正在观看。没有安全问题,因为它是所有客户端。