4

ネタバレ

この Javascript インジェクション ゲームの問題 8 を解決しようとしています。

Erling Ellingsenによるコメントの 1 つで、この興味深いスニペットを見つけました。

(_=[].concat)()[0]

上記のスニペットとこれの違いは何ですか?

([].concat)()[0]

[].concat変数に代入すると何が変わるでしょうか? 明らかに、彼はグローバル ウィンドウ オブジェクトにアクセスしようとしているだけですが、これら 2 つの評価はどのように異なるのでしょうか?

4

1 に答える 1

2

これが以前に機能した理由は、以前のバージョンの ECMAScript で、 this 値がグローバル オブジェクト (つまりwindow) になるように指定されていたためです。ただし、ECMAScript 5 以降、 this の値は になりundefined、makeArray.prototype.concatはエラーをスローします。

ES3 では、ネイティブ関数がorのthis値で呼び出された場合 ( を使用して呼び出した場合など)、関数にグローバル オブジェクトが提供されます。undefinednullfunc()

ES5 では、ネイティブ関数の動作が変更され、コードが厳密モードでなくても、実際のundefinedまたは値を取得できるようになりました。null


2 つの違いは、1 つは関数の値であり、したがって間接的に呼び出されるのに対し、もう 1 つは関数への参照であることです。

GetValue()は、変数から参照の値を取得する内部関数です。これは、「直接」呼び出すときは呼び出されませんが、別の変数に代入してその結果を使用するときは、実際に呼び出されます ( source )。

2 つの違いの悪名高い例は、次の使用時eval()です。

var a = 0;
function test()
{   var a = 1, b;
    console.log(eval("a")); // 1
    console.log((b=eval)("a")); // 0
}
test();

ただし、あなたの例では、次のように機能します。

var a = [].concat;
// called as variable, not property
a(); // therefore it's global

// same as the following, as all these expressions call GetValue() interally
(0, [].concat)();
(random = [].concat)();
([].concat || 0)();

// but this doesn't work
[].concat(); // `this` is the new array, not global object
于 2013-10-09T05:45:58.910 に答える