iT邦幫忙

0

JS eval的替代方案深入研究

各位大大好,有問題想深究,我想不通所以來請教各位前輩
我試著做了一個計算機,最後的結果呈現,我是這樣寫的

final_result = makeDigital(eval(evaluation))
                           "^^^^"
display_result = final_result

主要是說,evaluation是字串,用eval進行運算後,就可以丟出來了
跟我前輩討論的結果,eval這個函數是禁用,我去找eval的替代用法

其中一個是這樣:

row_1 function new_eval(a) {
row_2     var func = Function;
row_3     return new func('return ' + a)();
}

我不是很能理解這個想法,然後我有試著去在下面這些點拆解

function new_eval(a){
let func = Function;
console.log("func:" + typeof func)
b = "return " + a
console.log("b:" + typeof b + ":" + b)
c= new func(b)()
console.log("c:" + typeof c + ":" + c)
}

拆完了以後,結果是長這樣:

func:function
b:string:return 9+6*23
c:number:147

我的想法有以下幾個:

  1. row_2的Function,是命func為等於一個class,而這個class是Function,在這個class底下命出來的物件,都會對帶入的參數進行運算,而所謂的運算就是會讓"return 9+1/3+0.33*6"被算出一個number來
  2. row_3的new func,而這個new func()就對"return " + a進行了計算機要做的運算
  3. row_3外面的那個return,就把new func()的運算結果丟出來
    我以為,這樣就跟eval一樣了啊,同樣都是會對字串進行運算......??!!
    我以為這還是會造成跟eval一樣的結果...
    我不確定自己的推論對不對
    我的腦袋在這裡卡住了,也針對Function跟js function做過一番google,目前無法收斂出一個結論來
    想請各位大神出手,幫忙解釋一下
froce iT邦大師 1 級 ‧ 2021-10-20 23:25:21 檢舉
> 我以為,這樣就跟eval一樣了啊,同樣都是會對字串進行運算......??!!

你沒想錯,但有你沒考慮到的東西。

return 後面只能接表達式,eval可以在裡面寫陳述式。
表達式是不能宣告新變數的,因此你的new_eval會比eval安全一點。
當然還是有辦法突破,例如多弄個函式(假設是test)把想做的寫在函式裡,然後new_eval("test()")

實際上的真正的寫法要像下面說的才安全。
要不然至少在new_eval檢查一下有沒有不合格的字串
謝謝前輩!!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

2
淺水員
iT邦大師 6 級 ‧ 2021-10-20 17:11:45
最佳解答

如果要認真做的話,應該要把字串解析為運算符號跟數字
再按照優先次序計算出結果
實作中可以把中序式改成後序式來處理

我很早以前寫的:函數繪製
可以參考裡面的 function_ana.js
這有解析使用者輸入的字串計算出函數值

使用範例

<input type="text" id="eq">
<input type="button" value="計算" id="btn">
<script src="function_ana.js"></script>
<script>
    document.querySelector('#btn').addEventListener('click', () => {
        let str = document.querySelector('#eq').value;
        let funcObj = new FSA(str);
        alert(funcObj.f(1)); //計算 f(1) 並顯示
    });
</script>

淺水員
謝謝前輩!!

我要發表回答

立即登入回答