この章では、`eval()`と`new Function()`という2つの動的コードの評価方法について見ていきます。
JavaScript コードを含む文字列 `str` が与えられると、`eval(str)` はそのコードを評価し、結果を返します。
> eval('2 ** 4')16
`eval()` を呼び出す方法は 2 つあります。
「関数呼び出しを経由しないで」とは「`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()` は関数オブジェクトを作成し、次のように呼び出します。
const func = new Function('«param_1»', ···, '«param_n»', '«func_body»');
前のステートメントは、次のステートメントと同じです。ただし、`«param_1»` などの文字列リテラルの中になくなったことに注意してください。
const func = function («param_1», ···, «param_n») {
«func_body»; }
次の例では、`new Function()` と関数式を使って同じ関数を 2 回作成しています。
const times1 = new Function('a', 'b', 'return a * b');
const times2 = function (a, b) { return a * b };
`new Function()` は非厳密モード関数を生成します
`new Function()` で作成された関数は、デフォルトではゆるやかです。関数本文を厳密モードにする場合は、手動で切り替える必要があります。
可能な限り、コードの動的評価は避けてください。
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
コードを動的に評価しなければならない場合