Почему одна переменная не определена за пределами IIFE, а другая нет? - PullRequest
4 голосов
/ 09 марта 2019

Я играл с IIFE, и я в замешательстве.Значение a равно undefined, а b - нет.Почему я могу получить доступ к значению b вне IIFE?

(function(){
  var a = b = 3;
})();

console.log("a defined? " + (typeof a !== 'undefined')); // false
console.log("b defined? " + (typeof b !== 'undefined')); // true

Ответы [ 2 ]

10 голосов
/ 09 марта 2019

Синтаксис объявления может сбивать с толку, потому что выглядит как синтаксис для обычных выражений. Это, однако, отличается.

var a = b = 3;

анализируется как

var a = (something);

В этом случае something - это b = 3, так что ваша функция выглядит так, как будто

b = 3;
var a = b;

«Голый» b = 3 без var, let или const создает неявную глобальную переменную . Таким образом, b виден вне функции, а a - нет.

7 голосов
/ 09 марта 2019

Существует четыре способа объявления переменной в JavaScript:

  • var, что приведет к тому, что эта переменная будет объявлена ​​функцией.
  • let / const, который будет охватывать эту переменную объявленным блоком.
  • Неявное объявление, которое будет охватывать эту переменную глобально (если только оно ранее не было объявлено в другой области, в этом случае вместо этого оно будет переназначено).
var a = b = 3;

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

Вне функции объявлена ​​переменная b (поскольку она была неявно объявлена ​​глобально), а a - нет (поскольку она была объявлена ​​только в области действия функции).


Однако следует избегать неявно объявленных переменных (и желательно использовать let и const вместо var), поэтому приведенный выше код должен быть написан так:

(function() {
  let a = 3;
  let b = a;
});

Или, если вы действительно хотите, чтобы переменные также объявлялись вне функции:

let a, b;
(function() {
  // NOTE: not implicit declaration since a and b are both already declared
  a = 3;
  b = a;
})();
...