2013-02-28 10 views
6

いくつかのjsコードをでテストしました。Chrome Dev Consoleと少し混乱しています。JavaScript 'use strict';内部機能

Iは厳密モードでこのキーワードを呼ぶときにオブジェクトのメソッドではない機能が代わりにグローバルオブジェクトの未定義を受けるべきであることを知っています。

function test(){ 
    "use strict"; 
    return this===undefined;} 
test(); 

出力

"use strict"; 
function test(){ 
    return this===undefined;} 
test(); 

それでも

(function test(){ 
    "use strict"; 
    return this===undefined;}()); 

出力

明確にしたかっただけです。 ʕ•ᴥ•ʔ私はjsを初めて使う人です。

+2

同様の質問をお読みくださいhttp://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it – hexblot

+4

@hexblotしかし、これは質問に答えません。 – Christoph

答えて

2

それは、 Chromiumデベロッパーコンソールのバグで、thisが引き続きグローバルオブジェクトを参照してしまいます。同じコードは、ロケーションバーとドキュメントのjavascript:で指定されたとおりに動作します。

あなたはそれをテストすることができますようなので、(2コンソール入力):

var global = (function() { return this; }()); 

"use strict"; 
function test() { return this === global; } 
test(); 

及び(一の以上のコンソール入力)

var script = document.createElement("script"); 
script.type = "text/javascript"; 
script.appendChild(document.createTextNode(
    'function test() { "use strict"; return this === undefined; }; console.log(test());' 
)); 
document.body.appendChild(script); 

はクロムバージョン25.0.1364.97のDebian 7.0でテスト済み(183676) 。

+0

最初のテストは壊れたテストです。それをコンソールの代わりにスクリプトタグで実行しても、 '' use strict ''がスコープ内の*最初の行でなければならないので、' 'true''を取得します。あなたの例は、 'var global ... 'の後に来るので、ディレクティブは無視されます(仕様に従って)。 –

+0

@NathanWallいいえ、私の説明を参照してください。関数内で 'debugger;'を使用して呼び出しスタックを検査することをお勧めします。 – PointedEars

2

すべて問題ありません。あなたがコードをいくつかのHTMLページ(デベロッパーコンソールではない)で実行すると、結果は期待通りのものになります(常にthis===undefined)。最新のFirefox(Firebugの)でさらに

function test(){ 
    "use strict"; 
    return this===undefined;} 
test(); 
>> true 

これはちょうど別のChromeのバグ(?機能)のようです。それは、devコンソールを経由して渡されるコードとは少し異なるアプローチをしているように感じます。

<script> 
    console.log('Me First!'); 

    "use strict"; 

    function test(){ 
     console.log(this); 
    } 
    test(); 

</script> 

>>> "Me First!" 
>>> Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…} 

:しかし

<script> 
    "use strict"; 

    console.log('Me later!'); 

    function test(){ 
     console.log(this); 
    } 
    test(); 

</script> 

>>> undefined 
>>> "Me later!" 
4

あなたは気づいているだけでデベロッパーコンソールの動作方法の副作用である

も注文事項があることに注意してください。あなたがそこにコードを入力すると、これは(詳細はthis answerを参照してください)何が起こるか効果的である:

eval.call(null, "with (window) { \ 
        function test() { \ 
         'use strict'; \ 
         console.log(this); \ 
        } test(); \ 
       }"); 

これは、それは常に(グローバル実行コンテキストで実行することを意味しevalから間接的呼び出し、ありますブラウザ、それはwindowです)。

事実上、機能がグローバルオブジェクトにバインドされているので、あなたが(むしろコンソールに比べて)ウェブページでこれをやったかのようにthisは、グローバルオブジェクトへの参照を保持している:

function test(){ 
    "use strict"; 
    return this === undefined; 
} 

test(); // true 
test.call(window); // false 
+1

'window' *で参照されるオブジェクトは、実行コンテキストではありません。実行コンテキストは、抽象プログラムエンティティです。オブジェクトにスコープチェーン*があります。この場合、 'test'コールのコンテキストのために' window'が参照するオブジェクトをスコープチェーンに挿入する 'with'文があります。 – PointedEars

+0

@PointedEars - はい、もちろんです。私は「ウィンドウオブジェクトが属するレキシカル環境の環境レコード」と言っていたかもしれませんが、私が書いた方法は単純で、それでもポイントが得られると思います。 'with'ステートメントはこのケースでは何の違いもありません。引数が評価されるコンテキストに影響を与える' eval'が呼び出される方法です。 –

+0

ここに 'with'ステートメントがあるかもしれません*相当かもしれません。グローバルオブジェクトの 'window'ホストプロパティが常にグローバルオブジェクトを参照していると誤って仮定したのは確かです。そのため、 'test()'呼び出しは 'global.window.test()'と同等です。ここで、 'global'はグローバルオブジェクトへの標準参照のスタンドインとなります。 – PointedEars

関連する問題