Vue TypeScript使用eval函數遇到的問題

正常情況下,項目裡不會用eval函數,但是萬一要調用一個全局的js庫,就需要用eval做些騷操作,這個時候編譯會提示:is strongly discouraged as it poses security risks and may cause issues with minification.

警告是可以忽略,剛開始我也沒當回事,有風險就有風險,可控,我知道自己寫的是啥。但是,今天我改代碼的時候出瞭問題。就是dev時候正常,但是打包以後,不按照預期執行,編譯出來的代碼就不是我要的邏輯。

問題的關鍵是:使用eval的函數不能是全局函數(需要包裝在一個對象裡),然後這個函數內容要簡單,不要裡面定義各種變量,然後被eval調用,免得被編譯時候優化掉

簡單的代碼實例問題

上一段簡單的代碼:

<template>
  <div>
    <button @click="btn">測試</button>
  </div>
</template>
<script setup lang="ts">
function myfun(param:number){
    let ret = 0
    eval("ret = param+1")
    return ret;
}
function btn() {
  let ret = myfun(1);
  console.log(ret);
}
</script>

dev運行在瀏覽器點擊按鈕,輸出2,沒毛病

然後打包以後,運行就會是這樣,輸出為NaN

縮成一坨的這個代碼裡面,把我的myfun函數編譯成瞭這樣,也沒毛病:

function myfun(param){let ret=0;return eval("ret = param+1"),ret }

但是,調用時候變成瞭這樣!!!!

myfun調用的時候,傳入的參數哪裡去瞭???

let e=myfun();console.log(e)

因為沒有參數進入,eval裡的param+1結果就變成瞭NaN

解決方法

把代碼改成這樣,函數包裝到一個對象裡面:

<template>
  <div>
    <button @click="btn">測試</button>
  </div>
</template>
<script setup lang="ts">
const FunPack = {
  myfun(param:number){
    let ret = 0
    eval("ret = param+1")
    return ret;
  }
}
function btn() {
  let ret = FunPack.myfun(1);
  console.log(ret);
}
</script>

然後打包運行,輸出為2正常:

這個時候調用變成這樣,myfun的時候傳的參數正常

let e=FunPack.myfun(1);console.log(e)

問題的原理

感覺上,對於調用一個不在對象裡的函數,typescript編譯時候進行瞭更多優化,對於myfun函數,裡面eval函數那一行沒有類型系統,等於沒有,所以編譯時候理解成下面這樣,等於沒有eval那一行。等於param沒有被使用,所以調用函數時候,覺得這個參數沒有用,就給吃瞭。。。

function myfun(param:number){
    let ret = 0
    return ret;
}

同理,如果myfun裡面定義瞭別的變量,用來給eval使用,但是別的地方沒有使用,編譯時候,這個變量就會被編譯器認為無效,然後被吃掉,比如myfun定義成這樣,打包運行就會報錯dat is not defined

function myfun(param:number){
    let ret = 0
    let dat = param + 10;
    eval("ret = dat+1")
    return ret;
}

一勞永逸的方法

雖然通過把函數封裝到對象,可以解決問題,但是,也說不好ts編譯器後續會不會關於對象的方法調用也進行這種優化。

所以還有一個解決方法,就是在函數裡把param用一下,讓編譯器覺得它被使用瞭,別吃掉。

比如改成這樣,把param輸出一下。。。

function myfun(param:number){
    let ret = 0
    console.debug(param);
    eval("ret = param+1")
    return ret;
}

到此這篇關於Vue TypeScript使用eval函數遇到的問題的文章就介紹到這瞭,更多相關Vue TypeScript使用eval函數內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: