Комментарии 21
TL;DR: таки eval, просто не тот eval, а CSS calc.
Я бы не назвал этот вариант "простейшим". Есть же способ через new Function(...), с дополнительными плюшками.
соглашусь и возможно даже это будет более быстрым решением, но для моей задачи требовалось отказаться и от eval и от Function.
Данный код гуляет на просторах интернета и вполне рабочий способ
const rgx = /(?:(?:^|[-+_*/])(?:\s*-?\d+(\.\d+)?(?:[eE][+-]?\d+)?\s*))+$/; function parse(str) { if (!rgx.test(str)) return 'invalid entry!' return Function('use strict'; return (<span class="hljs-subst">${str}</span>))() }
то каким-то образом отрицательное число получается...
Так оно и есть отрицательное
Что это такое я сейчас прочитал?
Как говорил Дью, я вот знаю как. Я не знаю зачем. Regexp для валидации инпута и new Function и дело в шляпе.
Мне необходимо проводить порядка 100т. операций или даже больше, в таком случае Function не будет особо приятным решением
15118 - время 50т. операций через Function()
1154 - время 50т. операций через calc()
В среднем моё решение в 8 раз быстрее
Вы покажите, как вы считаете это время. Потому что я никогда не поверю, что вызов ванильной функции js в 8 раз медленнее, чем изменение css и потом его чтение.
Звучит как полный бред, лучшее е привезите примеры кода который вы сравнивали. Невозможно поверить что создание элемента и просчет его стиля быстрее чем просто выполнение функции.
Требую тег "ненормальное программирование"
Очень странный подход, однако. Очевидно, что если Вам важна скорость написания кода, то использовать стоит eval. Он и работать должен быстрее, чем предложенный в статье метод. Если хотите предотвратить возникновение уязвимостей и считать все так же быстро - напишите алгоритм Дейкстры «Сортировочная станция» для перевода в польскую обратную запись. На Хабре об этом уже писали - https://habr.com/ru/post/100869/.
Ну вот, ни рекурсивного спуска тебе, ни обратной польской нотации, калькулятор спрограммировал называется
// chatGPT code :)
function calculateMathExpression(expr, ...args) {
const sanitizedExpr = expr.replace(/[^0-9+-*/().]/g, '');
const fnBody = return ${sanitizedExpr};
;
const fn = new Function(fnBody);
return fn(...args);
}
но к сожалению использовать библиотеки нельзя
Почему?
Чудес не бывает. Либо мы строим синтаксическое дерево, либо вызываем функцию которая это делает за нас)
А как, перелопатив весь интернет, можно было не заметить единственное по сути решение без библиотек - польская обратная запись? Если нельзя библиотеки использовать, значит, писать алгоритм самому. А алгоритм один - польская обратная запись. Очень быстрый алгоритм. К сожалению, на лицо, результат физического отторжения дев комьюнити алгоритмики. 99% разработчиков (о фронтендерах молчу) исключают необходимость знания алгоритмики и всеми фибрами ненавидят олимпиадников. Любой тред заполняется супер аргументом "ононигденепригождается".
Простейшее решение калькулятора на js без eval();