eval()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

警告: 文字列から JavaScript を実行することは、非常に大きなセキュリティリスクを伴います。eval() を使用すると、悪意のある者が任意のコードを実行することがあまりにも簡単になります。下記の eval() を使わないでください!を参照してください。

eval() 関数は、文字列として表現された JavaScript コードを評価します。ソースはスクリプトとして解釈されます。

試してみましょう

console.log(eval("2 + 2"));
// Expected output: 4

console.log(eval(new String("2 + 2")));
// Expected output: 2 + 2

console.log(eval("2 + 2") === eval("4"));
// Expected output: true

console.log(eval("2 + 2") === eval(new String("2 + 2")));
// Expected output: false

構文

js
eval(script)

引数

script

JavaScript の式、文、または一連の文を表す文字列です。式には、既存オブジェクトの変数およびプロパティを含められます。これはスクリプトとして解釈されますので、 import 宣言(モジュールの中に存在しうる)は許可されていません。

返値

与えられたコードの評価結果の値を返します。評価結果が空の場合は、undefined を返します。もし script が文字列プリミティブでなければ、 eval() は引数を変更せずに返します。

例外

コードを評価している間に発生するあらゆる例外が発生します。もし script がスクリプトとして解釈できなかった場合は SyntaxError になります。

解説

eval() はグローバルオブジェクトの関数プロパティです。

eval() 関数の引数は文字列です。 ソース文字列をスクリプト本体として評価します。つまり、文と式の両方が使用可能です。コードの完了値を返します。式の場合は、式が評価された値です。多くの文や宣言も同様に完了値を持ちますが、その結果は意外なものになることがあります(例えば、代入の完了値は代入された値ですが、 let の完了値は undefined です)。そのため、文の完了値には頼らないことをお勧めします。

厳格モードでは、 eval という名前の変数を宣言したり、 eval に代入したりすることは SyntaxError になります。

js
"use strict";

const eval = 1; // SyntaxError: Unexpected eval or arguments in strict mode

eval() の引数が文字列でない場合、eval() は引数を変更せずに返します。次の例では、プリミティブの代わりに String オブジェクトを渡すと、 eval() は文字列を評価するのではなく、 String オブジェクトを返します。

js
eval(new String("2 + 2")); // "2 + 2" を含む String オブジェクトを返す
eval("2 + 2"); // 4 を返す

一般的な方法でこの課題をうまく回避するには、eval() に渡す前に、自分で引数を文字列に変換することができます。

js
const expression = new String("2 + 2");
eval(String(expression)); // 4 を返します

直接的または間接的な eval

eval() の呼び出しには、直接的な eval と間接的な eval の 2 つのモードがあります。直接的な eval は eval( ) が唯一の形です(呼び出す関数の名前は eval で、その値はグローバルな eval 関数です)。それ以外のすべて は、エイリアス変数経由、メンバーアクセスやその他の式経由、またはオプショナルチェーン ?. 演算子を使用して呼び出すことも含めて、間接的なものです。

js
// eval を返すためにカンマ演算子を使用する間接的呼び出し
(0, eval)("x + y");

// オプショナルチェーンによる間接的呼び出し
eval?.("x + y");

// eval を格納し返すために変数を使用する間接的呼び出し
const geval = eval;
geval("x + y");

// メンバーアクセスによる間接的呼び出し
const obj = { eval };
obj.eval("x + y");

間接的な eval は、コードが別個の