在現在項目中執行腳本的情況比較少。但是如果有這樣的要求,我們應該如何實現。
對於這個問題是鑒於有一個項目中實際遇到,就深入了解下。
一、eval
eval 是全局對象的一個函數屬性。
eval 接收的是一個字符串的腳本,如果不是字符串,會直接返回。
console.log(eval('2+2')) // 4 console.log(eval(new String('2+2'))) // [String: '2+2']
eval 還有一些很大的問題缺陷:
1、執行較慢(必須調用 JS 解釋器)
2、安全問題(使用與調用者相同權限執行代碼,這樣會導致惡意代碼被執行)
所以建議謹慎或者不使用 eval!
二、Function
在 JS 中每一個函數都是 Function 對象。
我們再寫代碼的時候用的:函數聲明、函數表達式、箭頭函數等寫的都是 Function 對象。
function add(x, y) { return x + y } console.log(add.constructor === Function) // true let add1 = function (x, y) { return x + y } console.log(add1.constructor === Function) // true let add2 = (x,y)=>{ return x + y } console.log(add2.constructor === Function) // true
那么我們也可以直接用 Function 構造函數動態的創建函數。
/** * Function([arg1[,arg2...]],functionBody) * 1、前面的是動態創建函數的參數 * 2、要創建的函數的函數體 */ const adder = new Function('a','b','return a+b') console.log(adder.constructor === Function) // true
Function 和 eval 是有區別的:
1、接收參數不一樣:Function 的函數體是可以接收字符對象,eval 只能是字符
2、eval 是直接執行傳入的語句等,Function 是創建了一個函數(根據需要是否有返回 return 不能忘記)
3、Function 是在全局執行的(只能訪問全局變量和自己變量,創建這個函數的作用域也不可以),eval 有自己調用的作用域(這個地方不安全,會被第三方查看)
const adder1 = new Function('a','b',new String('return a+b')) console.log(adder1(3,4)) // 7 可以接收 String 對象 // 需要在瀏覽器環境下執行 var x = 5 function createFun() { var x = 10 return new Function('return x;') } const fun1 = createFun() console.log(fun1()) // 5