Как использовать eval в программе - PullRequest
1 голос
/ 14 января 2020

Я разрабатываю программу javascript - графический калькулятор. Пользователь вводит уравнение (например, x * x + 2 * x) в текстовое поле, нажимает кнопку «получить ответ» и должен получить график. Если я напишу в функции f (x) выражение, такое как «Math.sin (x)», оно прекрасно работает, но когда я пытаюсь использовать метод eval для оценки кода пользователя, программа перестает работать. Я новичок в javascript. Любая помощь будет оценена! JavaScript код

//vars
var points = "";
var input = document.querySelector("#input");
var evaluate = document.querySelector("#evaluate");

evaluate.addEventListener('click', function() {
  document.body.appendChild(makeSVG(svgData));
});

function f(x) {
  return eval('(function() { x=' + x + ';' + input.value + ';}())');
}

function getPoints() {
  for (var i = -10; i < 10.0; i += 0.25) {
    var x = 10 * i + 100;
    var y = -10 * f(i) + 100;
    points += "" + x + "," + y + " ";
  }
  return points;
}

var svgData = [{
    type: 'svg',
    data: {
      viewBox: "0 0 500 200"
    }
  },
  {
    type: 'polyline',
    data: {
      fill: "none",
      stroke: "black",
      strokeWidth: "1",
      points: getPoints()
    }
  },
];

function getNode(n, v) {
  n = document.createElementNS("http://www.w3.org/2000/svg", n);
  for (var p in v) {
    n.setAttributeNS(null, p.replace(/[A-Z]/g, function(m, p, o, s) {
      return "-" + m.toLowerCase();
    }), v[p]);
  }
  return n
}

function makeSVG(data) {
  var result;
  data.forEach(
    function(elem, index, array) {
      if (index)
        result.appendChild(getNode(elem.type, elem.data));
      else
        result = getNode(elem.type, elem.data);
    }
  );
  return result;
}
<!DOCTYPE html>

<html>

<head>
  <title>Graphing Calculator</title>
</head>

<body>
  <h1>Graphing Calculator</h1>
  <form>
    <input id="input" type="text">
    <button id="evaluate" type="button">Get answer</button>
  </form>
  <script type="text/javascript" src="code.js"></script>
</body>

</html>

Ответы [ 2 ]

2 голосов
/ 14 января 2020

В IIFE нет необходимости в f(). Просто позвоните eval(x). Он будет выполняться в области f(), поэтому он может получить доступ к x.

Другая проблема заключается в том, что вы вызываете getPoints() при инициализации svgData, но пользователь еще не заполнено в поле ввода. Это нужно сделать в обработчике кликов.

//vars
var points = "";
var input = document.querySelector("#input");
var evaluate = document.querySelector("#evaluate");

evaluate.addEventListener('click', function() {
  svgData[1].data.points = getPoints();
  document.body.appendChild(makeSVG(svgData));
});

function f(x) {
  return eval(input.value);
}

function getPoints() {
  for (var i = -10; i < 10.0; i += 0.25) {
    var x = 10 * i + 100;
    var y = -10 * f(i) + 100;
    points += "" + x + "," + y + " ";
  }
  return points;
}

var svgData = [{
    type: 'svg',
    data: {
      viewBox: "0 0 500 200"
    }
  },
  {
    type: 'polyline',
    data: {
      fill: "none",
      stroke: "black",
      strokeWidth: "1",
      points: null
    }
  },
];

function getNode(n, v) {
  n = document.createElementNS("http://www.w3.org/2000/svg", n);
  for (var p in v) {
    n.setAttributeNS(null, p.replace(/[A-Z]/g, function(m, p, o, s) {
      return "-" + m.toLowerCase();
    }), v[p]);
  }
  return n
}

function makeSVG(data) {
  var result;
  data.forEach(
    function(elem, index, array) {
      if (index)
        result.appendChild(getNode(elem.type, elem.data));
      else
        result = getNode(elem.type, elem.data);
    }
  );
  return result;
}
<!DOCTYPE html>

<html>

<head>
  <title>Graphing Calculator</title>
</head>

<body>
  <h1>Graphing Calculator</h1>
  <form>
    <input id="input" type="text">
    <button id="evaluate" type="button">Get answer</button>
  </form>
  <script type="text/javascript" src="code.js"></script>
</body>

</html>
1 голос
/ 14 января 2020

Во-первых, обратите внимание, что eval всегда следует использовать осторожно, поскольку он позволяет выполнять произвольный код из пользовательского ввода. В вашем случае это не может быть действительно вредным, потому что позволяет пользователю выполнять код только на его собственной странице.

Ваша f() функция содержит eval, которая содержит ненужную самовыполняющуюся функцию. Более того, эта самоисполняющаяся функция ничего не возвращает. Попробуйте вместо этого:

function f(x) {
  return eval(input.value);
}
...