column

ITコラム

colmun_main7879

プログラミングノウハウ

2017.11.22

JavaScript【 eval 】 ~ ソースコードの評価と実行

eval 関数は、指定した文字列が「 JavaScriptのプログラムコードとして正しいか 」を評価した上で それを実行する関数です。
プログラムコードが動的に生成される場合などで必要とされる関数ですが、使用にはリスクも伴います。
今回は、このような eval 関数の使い方とリスクについて紹介します。

なお、未経験からITエンジニアへの就職に興味がある方や未経験からプログラミングを効率よく学びたいと考えている方は、就職率98.3%で受講料無料のプログラミングスクールプログラマカレッジもおすすめです。

1. eval 関数の使い方

 
eval 関数は、引数に指定した文字列を JavaScript のプログラムコードとして評価し、有効と評価された場合は それをそのまま実行する関数です。

次のように記述して、使用します。

eval( 文字列 );

eval 関数の引数には、評価対象となる JavaScript のプログラムコードを文字列で指定します。

eval 関数の返り値は、以下の通りです。

• 引数の文字列が JavaScript のプログラムコードとして有効と評価された場合は、プログラムが実行されて、その値が返る

• 引数の文字列が JavaScript のプログラムコードとして無効と評価された場合は、プログラムは実行されず、undefined が返る

• 有効と評価されたプログラムコード内で 複数の式が実行された場合は、最後に実行された式の結果が返る

 
eval 関数を実行して、返り値を表示します。
実行ボタンをクリックしてみて下さい。

eval(“1+1”) 
  
 

eval(“let i = 1+1; i*2”) 
  
 

eval(“let i = 1”) 
  
 

eval(“‘あいう'”) 
  
 

eval(“let str = ‘あいう'”) 
  
 

eval(“[1,2,3,4]”) 
  
 

eval(“for(let i=0;i<10;i++){i;}") 
  
 

eval(“for(let i=0;i<0;i++){i;}") 
  
 

eval(“new Date()”) 
  
 

 
「 eval(“‘あいう'”) 」は、値そのものの「 あいう 」が返りますが、「 eval(“let str = ‘あいう'”) 」は、「 undefined 」が返ります。

変数の宣言のみの「 eval(“let str = ‘あいう'”) 」は、JavaScript のプログラムコードとして間違っているわけではありませんが、eval 関数の評価対象としては不適当という判断だと思います。

また、「 eval(“for (let i=0; i<0; i++){i;}”) 」のように、初期値と条件との設定に誤りがあるような場合も、「 undefined 」が返ります。

 
上のサンプルのソースコードは次の通りです。

<script type="text/javascript">
function disp() {
    document.getElementById("dat").value = eval("1+1");
}
function disp2() {
    document.getElementById("dat2").value = eval("let i = 1+1; i*2");
}
function disp3() {
    document.getElementById("dat3").value = eval("let i = 1");
}
function disp4() {
    document.getElementById("dat4").value = eval("'あいう'");
}
function disp5() {
    document.getElementById("dat5").value = eval("let str = 'あいう'");
}
function disp6() {
    document.getElementById("dat6").value = eval("[1,2,3,4]");
}
function disp7() {
    document.getElementById("dat7").value = eval("for (let i=0; i<10;  i++){i;}");
}
function disp8() {
    document.getElementById("dat8").value = eval("for (let i=0; i<0;  i++){i;}");
}
function disp9() {
    document.getElementById("dat9").value = eval("new Date()");
}
</script>

<div style="background-color : #CCC; padding : 20px 20px 10px;">
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("1+1")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp()"></nobr>  
        <input type="text" id="dat"> 
    </div>
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("let i = 1+1; i*2")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp2()"></nobr>  
        <input type="text" id="dat2"> 
    </div>
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("let i = 1")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp3()"></nobr>  
        <input type="text" id="dat3"> 
    </div>
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("'あいう'")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp4()"></nobr>  
        <input type="text" id="dat4"> 
    </div>
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("let str = 'あいう'")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp5()"></nobr>  
        <input type="text" id="dat5"> 
    </div>
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("[1,2,3,4]")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp6()"></nobr>  
        <input type="text" id="dat6"> 
    </div>
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("for(let i=0;i<10;i++){i;}")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp7()"></nobr>  
        <input type="text" id="dat7"> 
    </div>
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("for(let i=0;i<0;i++){i;}")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp8()"></nobr>  
        <input type="text" id="dat8"> 
    </div>
    <div style="display:inline-flex; align-items: center;">
        <nobr style="width:450px;">eval("new Date()")</nobr> 
        <nobr><input type="button" value="実行" onClick="disp9()"></nobr>  
        <input type="text" id="dat9"> 
    </div>
</div>

▲目次へ戻る

 

2. eval 関数のリスク

 
eval関数には、次のようなリスクがあります。

• 悪意を持って用意された プログラムコードが eval関数の引数に混入されると、無制限に実行されてしまうという、セキュリティ面のリスク

• 通常の JavaScript プログラムを実行する場合と比較して 速度が低下してしまうという、パフォーマンス的なリスク。

このため、eval関数は、できる限り使用を避けるのが一般的です。

状況に応じて、代替手段があればその方法による、やむを得ず eval関数を使用する際にも リスク内容を考慮する、といった視点でコーディングすることが とても重要です。

▲目次へ戻る

無料説明会

最新記事

無料説明会に参加してみる

INTERNOUS,inc. All rights reserved.

無料オンライン説明会へ