eval()
、new Function()
(進階)eval()
new Function()
在本章中,我們將探討兩種動態評估程式碼的方法:eval()
和 new Function()
。
eval()
給定包含 JavaScript 程式碼的字串 str
,eval(str)
會評估該程式碼並傳回結果
> eval('2 ** 4')16
有兩種呼叫 eval()
的方法
「不透過函式呼叫」表示「任何看起來與 eval(···)
不同的東西」
eval.call(undefined, '···')
(使用函式的 .call()
方法)eval?.()
()(使用選擇性鏈結)(0, eval)('···')
(使用逗號運算子)globalThis.eval('···')
const e = eval; e('···')
以下程式碼說明了差異
.myVariable = 'global';
globalThisfunction func() {
const myVariable = 'local';
// Direct eval
.equal(eval('myVariable'), 'local');
assert
// Indirect eval
.equal(eval.call(undefined, 'myVariable'), 'global');
assert }
在全域內容評估程式碼比較安全,因為程式碼存取的內部較少。
new Function()
new Function()
會建立一個函式物件,並以以下方式呼叫
const func = new Function('«param_1»', ···, '«param_n»', '«func_body»');
前一個陳述式等同於下一個陳述式。請注意,«param_1»
等不再在字串文字內。
const func = function («param_1», ···, «param_n») {
«func_body»; }
在以下範例中,我們建立了同一個函式兩次,第一次透過 new Function()
,然後透過函式表達式
const times1 = new Function('a', 'b', 'return a * b');
const times2 = function (a, b) { return a * b };
盡量避免動態評估程式碼
JavaScript 經常是動態的,因此您不需要 eval()
或類似的函式。在以下範例中,我們使用 eval()
(A 行) 所執行的動作,也可以在沒有它的情況下順利執行 (B 行)。
const obj = {a: 1, b: 2};
const propKey = 'b';
.equal(eval('obj.' + propKey), 2); // (A)
assert.equal(obj[propKey], 2); // (B) assert
如果您必須動態評估程式碼
new Function()
而非 eval()
:它會在全域背景下執行其程式碼,而且函式會提供一個乾淨的介面給已評估的程式碼。eval
而非直接 eval
:在全域背景下評估程式碼較為安全。