Почему «this» в анонимной функции undefined при использовании strict?


86

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

Пример:

(function () {
    "use strict";

    this.foo = "bar"; // *this* is undefined, why?
}());

Протестируйте в скрипке: http://jsfiddle.net/Pyr5g/1/ Проверьте регистратор (firebug).


4
Обратите внимание, что это не имеет ничего общего с анонимными функциями, а не с методом вызова. См. Эту измененную скрипку (посмотрите журнал консоли).
Phrogz

@Phrogz: Возможно, отсюда и возникла путаница. Спасибо что подметил это.
T. Junghans

Ответы:


102

Это потому, что до ECMAscript 262 edition 5 была большая путаница, если люди, которые использовали constructor pattern, забывали использовать newключевое слово. Если вы забыли использовать newпри вызове функции конструктора в ES3, thisссылаетесь на глобальный объект ( windowв браузере), и вы забиваете глобальный объект переменными.

Это было ужасное поведение, и люди в ECMA решили просто приступить thisк нему undefined.

Пример:

function myConstructor() {
    this.a = 'foo';
    this.b = 'bar';
}

myInstance     = new myConstructor(); // all cool, all fine. a and b were created in a new local object
myBadInstance  = myConstructor(); // oh my gosh, we just created a, and b on the window object

Последняя строка выдает ошибку в ES5 strict

"TypeError: this is undefined"

(что намного лучше)


4
Это имеет смысл. У вас есть ссылка для подтверждения заявления?
Rob W

1
@RobW: Мне пришлось бы обыскать себя, но я несколько раз слышал, как Дуглас Крокфорд сказал, что это было причиной такого решения.
jAndy

1
Он упоминается в книге Крокфорд JavaScript: The Good Parts. Это подробно описано. Но не о решении ECMA.
madr

1
Это логическая причина, по которой в строгом режиме по умолчанию установлено значение undefined. Другая логическая причина - эффективность, другая логическая причина - то, что this === windowсбивает с толку и пропускает глобальную область видимости как токен в функции
Рейнос

2
@jAndy: Спасибо за ответ. Это имеет смысл. Я также нашел краткое объяснение изменений this на javascriptweblog.wordpress.com/2011/05/03/… : «В частности, если первый аргумент для вызова или применения имеет значение null или undefined, значение this вызываемой функции не будет преобразован в глобальный объект ".
Т. Юнгханс

15

Существует механизм, называемый «бокс», который обертывает или изменяет thisобъект перед входом в контекст вызываемой функции. В вашем случае значение thisдолжно быть таким, undefinedпотому что вы не вызываете функцию как метод объекта. Если нестрогий режим, в этом случае он заменяется windowобъектом. В strictрежиме всегда неизменен, поэтому undefinedздесь.

Вы можете найти больше информации на
https://developer.mozilla.org/en/JavaScript/Strict_mode.


@samuel, так как мы можем присвоить переменную объекту окна в строгом режиме ??
Null Pointer

8

Согласно ответу This Stack Overflow , вы можете использовать thisвнутри анонимных функций, просто вызывая их .call(this)в конце.

(function () {
    "use strict";

    this.foo = "bar";
}).call(this);

4
Обратите внимание, что в этом случае thisбудет Windowобъект, который может быть нежелательным
Ninjakannon

Этот ответ не объясняет заданный вопрос.
Anvesh Checka
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.