Определение против инициализации - PullRequest
3 голосов
/ 26 февраля 2012

В чем разница между объявлением, определением и инициализацией? Пример:

// Is this a declaration?
var foo;

// Did I defined object in here (but it is empty)?
var foo = {};

// Now that object is initialized with some value?
var foo = {first:"number_one"};

Ответы [ 4 ]

5 голосов
/ 26 февраля 2012

Первый пример - это объявление. Вы объявили переменную с идентификатором foo. Вы еще не дали ему значение, поэтому оно будет undefined:

var foo;
console.log(foo); //undefined

Второй пример - это объявление и присвоение. Вы присвоили пустой литерал объекта переменной с идентификатором foo. Как отмечено в комментариях, это фактически сокращение от:

var foo;
console.log(foo); //undefined
foo = {};
console.log(foo); //Object

Третий пример - другое объявление и другое присвоение. Вы присвоили другой литерал объекта foo.

Редактировать (см. Комментарии)

Поведение вашего кода немного отличается в зависимости от того, планировали ли вы каждый пример как независимую программу или как написанную (одну программу).

Если вы относитесь так, как написано:

Поскольку объявления переменных в JavaScript поднимаются до верхней части области, в которой они появляются, переопределение переменных не имеет никакого эффекта. Итак, первая строка объявляет переменную foo.

Вторая строка назначает пустой литерал объекта для foo, а третья строка назначает другой литерал объекта для foo. Оба эти назначения относятся к одному и тому же foo.

Что действительно происходит, так это:

var foo;
foo = {}; //No `var` keyword
foo = {first:"number_one"}; //No `var` keyword

Если вы обрабатываете каждую строку как отдельную программу:

Первая программа объявляет переменную с именем foo. Это значение undefined.

Вторая программа объявляет переменную с именем foo, а затем присваивает ей литерал пустого объекта.

Третья программа объявляет переменную с именем foo, а затем назначает литерал объекта с одним свойством.

2 голосов
/ 26 февраля 2012

Вы правильно поняли.

var foo;        // Is this a declaration ?

Да, вы объявили, что есть переменная с именем foo, но не определили foo (поэтому foo не определено).

var foo = {}    // Did I defined object in here (but it is empty) ?

Да, теперь вы «определили» foo ... у него есть значение, оно больше не является неопределенным. var foo = 5 также считается «определяющим» его.

var foo = {first:"number_one"}  // Now that object is initialized with some value ?

Вы могли бы сказать, что это "инициализировано", но на самом деле это просто семантика. «Объявлено» и «определено» немного более значимо.

0 голосов
/ 26 февраля 2012

Когда вы объявляете переменную с var foo;, вы фактически гарантируете, что она будет принадлежать области, в которой вы ее определили. То, что вы называете определением и инициализацией, на самом деле является присваиванием значения.

Рассмотрим следующий фрагмент кода в качестве примера:

(function () {

  // definition
  var foo;

  function assignFoo(x) {
    // assignment
    foo = x;
  }

  assignFoo(5);

  console.log(foo);

})();

Скажем, вы не всегда должны присваивать значение в рамках определения. Но это наиболее распространенный вариант использования, который обычно выполняется с помощью var foo = 5.

Вот так.

0 голосов
/ 26 февраля 2012

Запустите код ниже:

var foo;
console.dir(foo);
var foo = {};
console.dir(foo);
var foo = {first:"number_one"};
console.dir(foo);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...