我有兩個陣列 - 一個包含布林值,另一個包含運算子:
to_eval = [true, true, false, false]
ops=['&&', '||', '&&']
出于這個我想建立一個表達
result = true && true || false && false
哪個應該根據優先規則評估為真
如果我遍歷評估的陣列,結果是錯誤的。
我可以構建一個字串并使用 Eval 或 Function - 但從我一直在閱讀的內容來看,這可能會導致 Web 應用程式中的安全問題。
Javascript中是否有一種方法可以構建運算式而不對其進行評估,直到它完全形成,以便在不使用Eval或Function的情況下觀察優先規則?
uj5u.com熱心網友回復:
您可以使用以下命令安全地為受信任的邏輯運算子創建映射函式Array#reduce
:
但是這種從左到右評估的方式沒有優先級,所以
true && true || false && false
將評估false
.eval
如果您想要更準確的結果,例如 JavaScript 如何決議事物,則使用適當的清理會更容易。
顯示代碼片段
const to_eval = [true, true, false, false];
const ops = ['&&', '||', '&&'];
const ops_map = {
'&&': (a, b) => a && b,
'||': (a, b) => a || b
};
const result = to_eval.reduce((acc, cur, i) => ops_map[ops[i-1]](acc, cur));
console.log(result);
通過適當的消毒,您可以安全地使用eval
:
const evaluate = (to_eval, ops = []) => {
const expression = to_eval.reduce((acc, cur, i) => {
let left = i === 1 ? !!acc : acc;
let op = {'&&': '&&', '||': '||'}[ops[i-1]];
if(typeof op !== 'string') {
op = '||'; // fallback
}
let right = !!cur;
return `${left} ${op} ${right}`
});
const result = eval(expression);
console.log(expression, ' => ', result);
return result;
}
const to_eval = [true, true, false, false]
const ops = ['&&', '||', '&&'];
evaluate(to_eval, ops);
evaluate([true], []);
evaluate(['alert(1)', 0, false], ['alert(2)', 'hasOwnProperty']);
uj5u.com熱心網友回復:
eval
如果確定您的兩個陣列具有預期值(布林值和預期運算子),您可以安全地呼叫。所以只需添加一些代碼來驗證兩個給定的輸入。
您可以執行以下操作:
function evaluate(bools, ops) {
// Verify the given arguments are as expected
if (!ops.every(op => ["&&", "||"].includes(op))) throw "invalid operator";
if (!bools.every(bool => typeof bool === "boolean")) throw "invalid operand";
if (bools.length !== ops.length 1) throw "length mismatch";
return eval(bools.map((bool, i) => bool " " (ops[i] ?? "")).join(" "));
}
let to_eval = [true, true, false, false];
let ops = ['&&', '||', '&&'];
let result = evaluate(to_eval, ops);
console.log(result);
uj5u.com熱心網友回復:
如果您清理輸入,則可以使用 eval (IE,驗證所有令牌都來自非常特定的允許令牌串列)。
function safeEval(expression) {
const allowed = ['true', 'false', '&&', '||'];
if (expression.split(/\s /).every(token => allowed.includes(token))) {
return eval(expression);
} else {
throw Error('Encountered forbidden token.');
}
}
console.log(safeEval('true && true || false && false'));
console.log(safeEval('undefined'));
這遠不是您可以撰寫的最有效的代碼,但它很簡單并且可以完成作業,并且添加對其他運算子和括號的支持是微不足道的。
或者,您可以按照您希望的優先順序自行評估運算子:
const expression = [true, '&&', true, '||', false, '&&', false];
for (let i = 0; i < expression.length; i) {
if (expression[i] === '&&') {
const left = expression[i - 1];
const right = expression[i 1];
expression.splice(i - 1, 3, left && right);
}
}
console.log(expression);
for (let i = 0; i < expression.length; i) {
if (expression[i] === '||') {
const left = expression[i - 1];
const right = expression[i 1];
expression.splice(i - 1, 3, left || right);
}
}
console.log(expression);
如果要添加對許多運算子的支持,您可能希望使此代碼更健壯且重復性更少,但這至少可以幫助您入門。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/495799.html
標籤:javascript 数组 布尔值 表达 评估
上一篇:如何在更新陣列時重新渲染模式
下一篇:在nasm程式集中增加一個變數