Использует ли оператор запятой контекст выполнения в 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