Понимание JavaScript с помощью частной функции и функции, выполняемой самостоятельно
Я читал Ангус Кролл, понимая этот блог, и нашел это
var a = {
b: function() {
var c = function() {
return this;
};
return c();
}
};
a.b();//window
Мне кажется, во время вызова c, c был внутри b. это должен быть вызывающий контекст (поправьте меня, если я ошибаюсь). когда он выполняется, почему контекст (это) с () является окном?
есть еще один пример, который я нашел в этом блоге
var a = {
b: function() {
return (function() {return this;})();
}
};
a.b(); //window
почему контекст b это окно? Всегда ли анонимная функция запускается в глобальном контексте?
2 ответа
Вот хороший способ понять this
(каламбур предназначен):
Значение this
внутри функции определяется способ вызова функции. За одним исключением, это не имеет отношения к тому, где определена функция, в какие другие функции она может быть вложена, в какой объект она была определена, в какую функцию она входит или что-то из этого.
Когда вы вызываете функцию с помощью вызова метода, как foo.bar()
или же foo[bar]()
, this
внутри функции находится foo
объект.
Когда вы вызываете функцию с обычным вызовом функции, как foo()
, this
в функции это window
объект, или если функция использует строгий режим, это undefined
,
Это единственное исключение - если сама функция или окружающий ее код имеет "use strict";
меняется this
для простого вызова функции. Для хорошего кода, который не должен иметь значения - вы не должны писать код, который зависит от this
быть window
возражать в любом случае.
В противном случае, что вас волнует, это какой объект this
ссылается на вызов метода. И это всегда определяется тем, как вызывается функция, а не тем, как она определена.
Давайте рассмотрим ваш первый пример.
Когда вы звоните a.b()
звонишь b
как метод a
объект. Так что внутри b
функция, this
такой же как a
,
Как это случается, нам не стоит это знать, потому что b
функция никогда ничего не делает с this
, Все, что он делает, это звонит c()
как обычная функция. Так внутри c
, this
это window
объект, или это будет undefined
если бы вы были в строгом режиме.
c
функция просто возвращает свое this
значение или window
, И это также возвращаемое значение из b
, Вот почему вы видите window
как результат: все это происходит от того, как код вызывает b
а также c
функции.
Теперь о втором примере: ну, это просто ужасно запутанный код, не так ли? Кто бы мог написать этот код и ожидать, что кто-нибудь поймет его с первого взгляда?
Итак, давайте превратим это в более читаемую форму. Эта строка является проблемой:
return (function() {return this;})();
Давайте возьмем выражение функции в скобках:
(function() {return this;})
и назначьте его временной переменной:
var temp = (function() {return this;});
Нам больше не нужны лишние скобки, и давайте сделаем отступ для кода для удобства чтения:
var temp = function() {
return this;
};
и мы можем назвать это temp
переменная как функция в return
заявление:
return temp();
Теперь мы можем положить это обратно в b
функция в примере кода:
var a = {
b: function() {
var temp = function() {
return this;
};
return temp();
}
};
a.b(); //window
Привет! Разве этот код не выглядит знакомым? На самом деле, он идентичен первому примеру, за исключением названия temp
переменная. Итак, теперь вы понимаете, почему он работает так же, как и первый.
Одним из ключей для поиска является new
Ключевое слово, которое устанавливает новый контекст. Не вижу new
? Тогда контекст не изменился, что означает this
не изменился Если вы назвали это изнутри window
тогда это ваш контекст, и это ваш this
, (Это изменится, если вы используете call()
или же apply()
с областью, но это, очевидно, не относится здесь.)