2013-02-28 20 views
6

Przetestowano kod js w Konsoli programowej Chrome i jestem nieco zdezorientowany.JavaScript 'use strict'; wewnątrz funkcji

Wiem, że w trybie ścisłym funkcje, które nie są metody obiektu, gdy mowa ten kluczowe powinny otrzymywać niezdefiniowanej zamiast globalnego obiektu.

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

Wyjścia fałszywy.

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

Wciąż fałszywy.

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

Wyjścia prawda.

Chciałem tylko wyjaśnić. ʕ • ᴥ • ʔ Jestem nowy w js.

+2

proszę przeczytać podobne pytanie http://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it – hexblot

+4

@hexblot nie odpowiada to jednak na pytanie ... – Christoph

Odpowiedz

2

It to błąd w konsoli Chromium Developer Console, który powoduje, że this nadal odwołuje się do obiektu globalnego. Ten sam kod działa zgodnie z ustawieniem javascript: na pasku lokalizacji iw dokumentach.

Można sprawdzić, jak SO (2 wejścia konsoli):

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

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

i (jedno lub więcej wejść konsoli)

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); 

testowana w Chromium Wersja 25.0.1364.97 Debiana 7.0 (183676) .

+0

Twój pierwszy test to zepsuty test. Nawet jeśli uruchomisz to w tagu skryptu zamiast w konsoli, nadal otrzymasz 'true', ponieważ' "use strict" 'musi być * pierwszą * linią w jego zasięgu. Twój przykład ma go po 'var global ...', więc dyrektywa jest ignorowana (zgodnie ze specyfikacją). –

+0

@NathanWall Nie, zobacz moje wyjaśnienie. Sugeruję użycie 'debuggera;' w funkcji do sprawdzenia stosu wywołań. – PointedEars

2

Wszystko w porządku. Jeśli uruchomisz swój kod za pośrednictwem strony HTML (nie konsoli programisty), wyniki spełniają oczekiwania (zawsze this===undefined).

Dodatkowo w najnowszy Firefox (Firebug):

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

Więc to wydaje się być po prostu kolejnym Chrome bug (funkcja?). Wydaje się, że ma nieco inne podejście do kodu przekazywanego za pośrednictwem konsoli dev.

Należy również pamiętać, że sprawy zamówienie:

<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…} 

Ale:

<script> 
    "use strict"; 

    console.log('Me later!'); 

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

</script> 

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

Co zauważyłeś jest po prostu efektem ubocznym drodze prace konsoli programisty. Kiedy tam wpisać kod, to skutecznie, co dzieje (patrz this answer więcej szczegółów):

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

To pośredni wywołanie eval, co oznacza, że ​​zawsze wykonać w globalnym kontekście realizacji (w przeglądarka, to jest window).

Skutecznie funkcja jest związana z globalnym obiektu i dlatego this posiada odniesienie do globalnego obiektu, a jeśli nie to na stronie internetowej (zamiast w konsoli):

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

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

Obiektem takim jak "okno" * jest * * nie * kontekst wykonania. Kontekst wykonania jest abstrakcyjną jednostką programową; ma łańcuch * zasięgu * z obiektami w nim. W tym przypadku byłoby to polecenie 'with', które wstawia obiekt, do którego odwołuje się' window' w łańcuchu zasięgu dla kontekstu wywołania 'test()'. – PointedEars

+0

@PointedEars - Tak, oczywiście. Mógłbym powiedzieć "rekord środowiska środowiska leksykalnego, do którego należy obiekt' window' ", ale sposób, w jaki go wprowadziłem był prostszy i wydaje mi się, że wciąż ma to znaczenie. A instrukcja 'with' nie robi różnicy w tym przypadku - jest to sposób, w jaki wywoływane jest' eval', które wpływa na kontekst, w którym jego argument jest oceniany. –

+0

Instrukcja 'z' tutaj * może * być znacząca; to na pewno jeśli założysz (IMO omyłkowo), że właściwość hosta 'window' obiektu globalnego zawsze odnosi się do obiektu globalnego. Ponieważ wtedy wywołanie 'test()' byłoby równoważne 'global.window.test()', gdzie 'global' byłoby stand-inem dla standardowego odniesienia do obiektu globalnego. – PointedEars

Powiązane problemy