2013-02-28 3 views
6

Протестирован код js в Консоль Chrome Dev, и я немного смущен.JavaScript 'use strict'; внутри функции

Я знаю, что в строгого режима функций, которые не являются методами объекта, когда упоминаются это ключевого слово должно получить неопределенную вместо глобального объекта.

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

It является ошибкой в ​​консоли разработчика 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); 

Испытано в Chromium версии 25.0.1364.97 Debian 7.0 (183676) ,

+0

Ваш первый тест - сломанный тест. Даже если вы запустите это в теге скрипта вместо консоли, вы все равно получите 'true', потому что' 'use strict '' должно быть * первой * строкой в ​​своей области. В вашем примере это происходит после 'var global ...', поэтому директива игнорируется (согласно спецификации). –

+0

@NathanWall Нет, см. Мои разъяснения. Я предлагаю вам использовать 'debugger;' в функции для проверки стека вызовов. – PointedEars

2

Все в порядке. Если вы запускаете свой код через некоторую HTML-страницу (а не консоль dev), результаты соответствуют ожиданиям (всегда this===undefined).

Кроме того, в последнем Firefox (Firebug):

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

Так что это, кажется, только другой Хром ошибки (функция?). Похоже, что у него несколько иной подход к коду, который передается через 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' *, является * * не * контекстом выполнения. Контекст выполнения - абстрактный объект программы; он имеет цепочку * видимости * с объектами в ней. В этом случае это будет оператор 'with', который вставляет объект, на который указывает« окно »в цепочке областей, для контекста вызова' test() '. – PointedEars

+0

@PointedEars - Да, конечно. Я мог бы сказать «запись среды лексической среды, к которой принадлежит объект« window' », но, как я выразился, это было проще, и я думаю, что все еще имеет смысл. И выражение 'with' не имеет никакого значения в этом случае - это способ, которым вызывается' eval', который влияет на контекст, в котором оценивается его аргумент. –

+0

Операция 'with' здесь * может * быть существенной; это, конечно, если вы предположите (IMO ошибочно), что свойство 'window' хоста глобального объекта всегда ссылается на глобальный объект. Потому что тогда вызов 'test()' был бы эквивалентен 'global.window.test()', где 'global' был бы stand-in для стандартной ссылки на глобальный объект. – PointedEars

Смежные вопросы