2016-11-04 2 views
-1

У меня есть строковое выражение, подобное этому 10/3*4-7, и я хочу знать, существует ли какой-то тип javascript-метода, который может преобразовать строку в фактическое выражение, чтобы я мог получить ответ . У меня есть функция, которая случайным образом генерирует числа и операторы, и я хочу получить результат из уравнения. Тем не менее, функция, которую я создал для получения результата, вычисляет только слева направо. Это не соответствует приоритету оператора, где * и/вычисляются сначала и тому подобное. Есть ли что-то в javascript, который может это сделать, или мне нужно создать функцию, чтобы сделать что-то подобное?Как преобразовать строковое выражение math в фактическое математическое выражение

+0

Да, вы можете буквально использовать '10/3 * 4-7' – Tibrogargan

+0

Пожалуйста, смотрите ниже в моем ответе – Aruna

ответ

3

Я бы рекомендовал использовать библиотеку, такие как Math.js как это будет разобрать математическое выражение, используя регулярные выражения. Это позволит избежать открытия приложения до атак типа Cross-Site scripting (XSS).

var answer = math.eval('10/3*4-7'); 
 
console.log(answer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.6.0/math.min.js"></script>

+0

Спасибо и всем остальным, которые пытались мне помочь –

+0

минорная вещь здесь: под обложками math.js использует 'Function()'. Большая вещь, которую вы получаете от его использования, заключается в том, что ваше выражение будет сначала проанализировано и должно быть правильным. – Tibrogargan

+0

@Tibrogargan - Я не могу найти его в исходном коде. Хотите опубликовать ссылку? –

-1

Существует довольно дискуссия here о том, почему вы не должны использовать eval(), если нет ясных альтернатив. Использование eval() в данном случае совершенно не нужно, как показано в примере ниже:

var expression = "10/3*4-7"; 
 
var foo = Function('"use strict"; return '+expression); 
 

 
console.log(foo());

+0

я не знаю, о«всех broswers», но этот механизм был в JavaScript не менее 19 лет (с ECMA 1.0). Я был бы удивлен, если бы были обычные браузеры, которые не поддерживали его. – Tibrogargan

+0

Функция JS стандартная и поддерживается во всех браузерах. Однако это небезопасно буквально по той же причине, что и eval. Для этого нет никакой пользы. –

+0

@Iwrestledabearonce с использованием eval() отключит оптимизацию компилятора. – Tibrogargan

0

Эта функция принимает либо строковое выражение, или массив символов, которые создают выражение.

function calculate(expression) { 
 
    "strict mode"; 
 
\t if(Array.isArray(expression)) 
 
\t \t expression = expression.join(""); 
 
    var allowedChars = "1234567890%^*()-+/. "; 
 
    for (var i = 0; i < expression.length; i++) 
 
    if (allowedChars.indexOf(expression.charAt(i)) < 0) 
 
     throw new Error("Invalid expression: unexpected '" + expression.charAt(i) + "' in '"+expression+"'"); 
 
    return eval(expression); 
 
} 
 

 
try{ 
 
\t alert(calculate("4+4")); 
 
\t alert(calculate([7,"+",9,"/",34])); 
 
\t alert(calculate("45/3")); 
 
\t alert(calculate("100 * cheeseburger")); 
 
}catch(e){ 
 
\t alert(e.message); 
 
}

Вот почему это безопасно:

  1. Неправильное использование Eval открывает код для атак путем внедрения
    • В strict modeeval не может вводить новые переменных в окружающий объем. (Так как это в конце своей собственной функции, в любом случае ничего не происходит в этой области.)
    • Функция выдает ошибку, если присутствует какой-либо символ, который не является частью математического выражения, что делает невозможным инъекцию.
  2. С eval, отладкой не может быть более сложными (без номеров строк и т.д.)
    • В этом случае функция выдает ошибку, которая включает в себя номер строки. Код eval 'd - это только одна строка, поэтому это не имеет значения.
  3. eval «d код не выполняется медленнее (нет возможности компиляции/кэш-код Эвальд)
    • В этом случае нет ничего компилировать/кэш, так что это не проблема.
Смежные вопросы