18

s次のような文字列は存在しますか

(new Function(s))();

eval(s);

動作が異なりますか?文字列がどのように評価されているかを「検出」しようとしています。

4

3 に答える 3

31

オブジェクトを確認しargumentsます。存在する場合は、関数内にいます。そうでない場合は、eval編集されています。

arguments次のようなtry...catchブロックにチェックを入れる必要があることに注意してください。

var s = 'try {document.writeln(arguments ? "Function" : "Eval") } catch(e) { document.writeln("Eval!") }';
(new Function(s))();
eval(s);

デモ

nnnnnnの懸念に対する解決策。このために、eval関数自体を編集しました。

var _eval = eval;
eval = function (){
    // Your custom code here, for when it's eval
    _eval.apply(this, arguments);
};

function test(x){
    eval("try{ alert(arguments[0]) } catch(e){ alert('Eval detected!'); }");
}
test("In eval, but it wasn't detected");​
于 2012-09-01T12:09:06.473 に答える
15

evalを再定義できないため、現在の回答は厳密モードでは機能しません。さらに、再定義evalは他の多くの理由で問題があります。

それらを区別する方法は、よく...それらの1つが関数を作成し、そうでないものを作成するという事実に基づいています。関数は何ができますか?彼らはreturn詰め込むことができます:)

それを悪用して、次のように何かを行うことができますreturn

// is in function
try {
     return true;
} catch(e) { // in JS you can catch syntax errors
     false; //eval returns the return of the expression.
}

したがって、例では:

var s = "try{ return true; }catch(e){ false; }";
eval(s); // false
Function(s)(); // true
(new Function(s))(); // true, same as line above
(function(){ return eval(s); })(); // the nested 'problematic' case - false
于 2013-12-19T19:59:55.787 に答える
2
if (new Error().stack.indexOf('at eval') > -1) {
    console.log('Oh noo, I am being evaled');
}
于 2020-11-21T09:53:46.457 に答える