3

私はまだ JavaScript に非常に慣れていません (ただし、コーディングに関してはそうではありません)。

ユーザー入力を受け入れるものを作成しようとしました。最初の文字が感嘆符の場合、その名前のオブジェクトを作成し、そのオブジェクトの「アクション」メソッドを実行しようとします。それ以外の場合は、通常のテキストのように扱われます (今のところアラート)

<script type="text/javascript">
function GetInput(input){

    // Trim the spaces off the beginning and end
    input = input.trim();

    if(input.charAt(0) != "!"){
        // Just some normal text
        alert(input);

        return true;
    }

/* Cut off the exclamation point, replace multiple spaces with one,
 * and get the arguments if any. args[0] = the command. */

    var args = input.substr(1).replace(/\s{2,}/g, " ").split(" ");

// Make sure the function is an object with a method named "action"
    if(eval("typeof "+args[0]+";") === "function"
        && eval("typeof "+args[0]+".prototype.action;") === "function"){

        eval("var command = new "+args[0]+"();");

        command.action(args);
    }else{
        alert('"'+args[0]+'" is not a command.');
    }

    return true;
}
</script>

これまでのところ、私が気付いている唯一の問題は eval ステートメントです。スイッチ/ケースを使用してevalをすべて一緒に使用したり、許可された関数の名前を含む配列を作成して、evalの前にその配列と入力を比較したりできることはわかっていますが、もっと良い方法があるはずです.

オブジェクトとメソッドを作成し、何も更新しないようにしたいだけです (ダックタイピングの主な用途の 1 つだと思います)。これはevalなしで可能ですか?eval(alert('u b haxed'))そうでない場合、「! 」や「!」などを避けるために文字列の入力をサニタイズする簡単な方法はありa;alert('u b haxed')ますか?

前もって感謝します

4

1 に答える 1

3

eval関数を取得するために一度だけ使用してから、変数ですべてを実行する必要があります。

var args = input.substr(1).split(/\s+/);
var fn = eval(args[0]);
if (typeof fn == 'function' && typeof fn.prototype.action == 'function') {
    var command = new fn();
    command.action(args);
} else {
    alert('"'+args[0]+'" could not be evaluated to a valid command.');
}

return true;

windowこれらのコンストラクターがグローバル変数である場合、オブジェクトのプロパティとしてそれらにアクセスすることもできます。

var fn = window[ args[0] ];
于 2012-12-03T01:23:31.250 に答える