Использует ли оператор запятой контекст выполнения в Javascript?
var a = 1;
var b = {
a : 2,
c : function () {
console.log(this.a);
}
};
b.c(); // logs 2
(b.c)(); // logs 2
(0, b.c)(); // logs 1
Первое понятно: для "this" указывается Object "b". Но почему второй регистрирует один и тот же результат? Я думал, что "this" следует указать на глобальный контекст выполнения. И третий, кажется, что оператор запятой влияет на контекст выполнения.
Ответы
Ответ 1
У вас действительно есть хороший угловой футляр!
Я беру на себя это:
- первый прост. Просто стандартный звонок. "." оператор позволяет вызывать настройку функции
b
как контекст выполнения.
- вторая - это точно одно и то же: парсеры полностью необязательны, и интерпретатор обрабатывает выражение внутри него как вызов связанной функции. На самом деле я этого не ожидал: я думал, что интерпретатор будет reset
this
глобальному объекту, но на самом деле он связывает его. Вероятно, именно так "случайные" пользователи языка не волнуются.
- третий является более стандартным (по крайней мере, для тех, кто живет на земле JavaScript): как только ваша функция передается в выражении (в данном случае оператором
,
) значение this
, связанное с контекст выполнения теряется. Итак, вы фактически проходите вокруг самой функции, больше не связанной с объявляющим объектом. Поэтому, когда вы называете это, this
будет передан как глобальный объект.
Смотрите так: (object.function)()
получает простое значение в object.function()
, потому что входящие парсеры полностью необязательны; (0, object.function)()
анализируется как (expression yielding a function)()
, который потеряет привязку object
к this
, поскольку функция уже несвязана.
Действительно хороший пример!
Ответ 2
Обратитесь к Косвенному eval-вызову, в котором содержится более подробная информация об этом.
( 0 , b.c ) ( )
|____| |_____| |_____|
Literal Operator Identifier
|_________________________|
Expression
|______________________________|
PrimaryExpression
|______________________________| |________|
MemberExpression Arguments
|________________________________________________|
CallExpression
Мы можем использовать оператор запятой для создания косвенного вызова b.c
, который заставит его выполнить в global context
, значение a
равно 1
в global context
.
Также результатом (b.c = b.c)()
является 1
> (b.c = b.c)()
1
Говоря в терминах ECMAScript, это связано с тем, что оператор - запятая (в примере (0, b.c)
) и =
(в (b.c = b.c)
пример) выполняет GetValue в своих операндах.
Другие форматы косвенных вызовов, как показано ниже
> (b.c, b.c)()
1
> (1? b.c: 0)()
1
> (__ = b.c)()
1