![見出し画像](https://assets.st-note.com/production/uploads/images/149392423/rectangle_large_type_2_8f4a1259b256e81b2527ab8933ac16f7.png?width=1200)
⚠️js eval()のやや安全な利用方法 間接的eval
evalは答えをくれるかもしれない。でも、それが禁じられている理由は何だ?なぜまだこの世に存在する?
JavaScriptのeval()とFunction()はどちらも文字列をコードとして実行する機能を提供しますが、その振る舞いと使い方にはいくつかの違いがあります。eval() 関数は、与えられた文字列を現在のスコープで直接評価し、実行します。これは、与えられた文字列が現在のローカルやグローバルスコープの変数にアクセスできることを意味します。しかし、これにはセキュリティリスクが伴うため、通常は使用が推奨されません。
let x = 10;
let result = eval('x + 10'); // 20
Function()
Function() コンストラクタは、新しい関数を生成します。この関数はグローバルスコープで実行され、現在のローカルスコープからは隔離されます。これは、スコープの汚染を避けるために有用です。Function()は最後の引数として関数の本体を表す文字列を取り、それ以前の引数は新しく生成される関数のパラメータ名となります。使用例は以下の通りです:
let x = 20;
let myFunction = new Function('a', 'b', 'return a + b + x;');
let result = myFunction(10, 5); // 35, x is taken from the global scope
主な違い
スコープの扱い:
eval()は現在のスコープで文字列を評価します。
Function()は新しい関数をグローバルスコープで生成し、現在のスコープとは隔離されます。
セキュリティ:
eval()を使用するとセキュリティリスクが高まる可能性があります。
Function()も文字列からコードを生成するリスクを伴いますが、少なくともローカルスコープの汚染を避けることができます。
パフォーマンス:
eval()は現在のコンテキストに依存するため、最適化が困難な場合があります。
Function()は新しい関数を一度だけコンパイルし、必要に応じて何度も呼び出すことができるため、パフォーマンスが向上することがあります。
間接的なevalという選択肢もありますか?
はい、JavaScriptでは「間接的なeval」という概念があります。これはeval()関数を間接的に呼び出す方法で、通常はグローバルスコープでコードを評価するために使われます。間接的なevalは、直接的なevalとは異なり、現在のローカルスコープではなく、グローバルスコープで実行されます。
間接的なevalの使い方
間接的なevalの実行は、eval()関数を変数に代入せずに、グローバル関数として間接的に実行することで行います。例えば、以下のように記述することができます:
let globalEval = eval;
let x = 10;
function test() {
let x = 20;
console.log(globalEval('x')); // 10, refers to the global 'x'
}
test();
この例では、globalEvalを通じてeval()が間接的に呼び出されています。test関数内のローカル変数xではなく、グローバル変数xが評価されています。
間接的なevalの特徴
間接的なevalは、以下のような特徴があります:
グローバルスコープでの実行:間接的なevalはグローバルスコープでコードを評価します。これにより、関数内のローカル変数へのアクセスを避け、グローバルな変数や関数のみを参照します。
セキュリティとスコープ:間接的なevalは、直接的なevalよりも少し安全性が高いとされることがありますが、それでも任意のコードを実行するリスクは存在します。セキュリティ対策としては、可能な限りevalの使用を避けることが推奨されます。
間接的なevalの使用は、特定の状況で有用かもしれませんが、一般的にはセキュリティリスクやパフォーマンスの観点から、他の方法を探求することが望ましいです。例えば、Function()コンストラクタを使用してコードを安全に実行する方法が代替として考えられます。
![](https://assets.st-note.com/img/1722599090497-V4Mr5KDqPh.png?width=1200)
いいなと思ったら応援しよう!
![あたり帳簿](https://assets.st-note.com/production/uploads/images/146045306/profile_76a0adfc7bd4b4908ef76d29ad61ae98.png?width=600&crop=1:1,smart)