** оператор не поддерживается в IE11. Как заменить его на Math.pow с помощью кода?

#javascript #jquery

#javascript #jquery

Вопрос:

У меня есть этот пример формулы:

 ((97000 * ((5.50/100)/12)) / (1 - ((1   ((5.50/100)/12))**(-1 * 120))))
  

Проблема в том, что этот код работает некорректно в IE11. Я пробовал этот метод для замены каждого ** на Math.pow , но я не могу заставить его работать правильно:

 function detectAndFixTrivialPow(expressionString) {
  var pattern = /(w )**(w )/i;
  var fixed = expressionString.replace(pattern, 'Math.pow($1,$2)');
  return fixed;
}

var expr = "((97000 * ((5.50/100)/12)) / (1 - ((1   ((5.50/100)/12))**(-1 * 120))))";
var expr2 = detectAndFixTrivialPow(expr);

console.log(expr);
console.log(expr2); // no change...  

Комментарии:

1. Проверьте консоль в IE11 dev tools, чтобы найти ошибку, которую вы можете отладить

2. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /… — ie 11 не поддерживает **

3. @RoryMcCrossan ^ — это xor .

4. просто напишите это правильно с первого раза.

5. Вы не найдете простого регулярного выражения — я уверен, что кто-нибудь сможет что-нибудь придумать, но, серьезно, если вы ДОЛЖНЫ поддерживать IE, то забудьте ES6 полностью — IE11 поддерживает только 11% ES6 — серьезно, он поддерживает только 99% ES5! и 1% ES2016 — придерживайтесь ES5, если вы должны поддерживать IE11 — или вырезать IE11, чтобы Internet Explorer был ближе к смерти от тысячи сокращений

Ответ №1:

Попытка сделать это с помощью регулярного выражения будет непростой. Вместо этого используйте транспилятор или, по крайней мере, анализатор ECMAScript.

Вот пример, как это можно сделать с помощью синтаксического анализатора esprima. Этот API создает дерево AST. Приведенный ниже код ищет ** оператор в этом дереве и собирает смещения, в которых должна измениться входная строка. Затем эти смещения сортируются в порядке убывания, чтобы применить их в правильном порядке к входной строке.

Обратите внимание, что этот код не пытается сохранить какие-либо круглые скобки. Данные во входных данных сохраняются, и для каждого из вызовов добавляется дополнительная пара Math.pow .

 function convert(input) {
    let modifs = [];
    
    function recur(ast) {
        if (Object(ast) !== ast) return; // not an object
        if (ast.type === "BinaryExpression" amp;amp; ast.operator == "**") {
            modifs.push(
                [ast.range[0], 0, "Math.pow("], 
                [input.indexOf("**", ast.left.range[1]), 2, ","],
                [ast.range[1], 0, ")"]
            );
        }
        Object.values(ast).forEach(recur);
    }
    recur(esprima.parse(expr, { range: true }));
    
    modifs.sort(([a], [b]) => b - a);
    
    let output = [...input];
    for (let params of modifs) output.splice(...params);
    return output.join("");
}

// Demo
let expr = "((97000 * ((5.50/100)/12)) / (1 - ((1   ((5.50/100)/12))**(-1 * 120))))"

let result = convert(expr);
console.log(result);  
 <script src="https://cdn.jsdelivr.net/npm/esprima@4.0.1/dist/esprima.min.js"></script>