0

ブラウザで次のコードを実行してみてください。

eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS COOL') + "')); })()");

THIS IS COOLただし、これを実行すると、次のように出力されます。

eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS "NOT" COOL') + "')); })()");

印刷する代わりに失敗しますTHIS IS "NOT" COOL

誰かがなぜこれが起こるのか説明できますか?


これに注意してください:

の結果JSON.stringify('THIS IS "NOT" COOL')は文字列です"THIS IS \"NOT\" COOL"

を実行しようとするJSON.parse("THIS IS \"NOT\" COOL")と失敗します。これは、JS パーサーが文字列"THIS IS \"NOT\" COOL"を として解釈するため"THIS IS "NOT" COOL"です。

を実行するJSON.parse(JSON.stringify('THIS IS "NOT" COOL'))と、文字列"THIS IS \"NOT\" COOL"が に直接渡されるため、機能しますJSON.parse

このシナリオでは機能するのに、前のシナリオでは機能しないのはなぜですか?

私の唯一の結論は、コードを実行する前に eval が渡されたものすべてを明示的にアンエスケープするということですが、それを確実に知り、なぜ eval がこのように動作するように設計されているのかを理解したいと思います。

4

1 に答える 1

2

ここでの問題は、文字のエスケープです。文字列連結の結果を見てください。

"(function() { console.log(JSON.parse('"THIS IS \"NOT\" COOL"')); })()"

これは実際の出力であり、文字列リテラルではないことに注意してください。\ここでは、エスケープ文字ではなくリテラル文字です (文字列について話していることを示すために外側の引用符のみを含めました)。

を使用するevalと、文字列は次のコードとして評価されます。

(function() { 
    console.log(JSON.parse('"THIS IS \"NOT\" COOL"')); 
})()

この時点で、\"実際には文字エスケープ シーケンスとして解釈されます。つまり、文字列リテラルのは次のようになります。 '"THIS IS \"NOT\" COOL"'

"THIS IS "NOT" COOL"

これは無効な JSON エンコード文字列です。

したがって、エラーが発生します

SyntaxError: Unexpected token N


eval渡された文字列に対して何もしません。取得した方法で解釈されます。

于 2013-07-02T20:14:06.887 に答える