Javascript: z = z ||[] выдает ошибку, когда не используется VAR - почему? - PullRequest
7 голосов
/ 30 января 2012

Просто из интеллектуального любопытства, почему javascript принимает

var z = z || [];

для инициализации z (как z может быть определен изначально)

, но без var выдает ошибку (в глобальном пространстве)

z = z || [];

(если z ранее не определено)

В глобальном пространстве вам не нужно использовать VAR, хотя я понимаю, что это может быть плохой практикой.

РаньшеВы говорите, что это дубликат вопросов, таких как

Какова цель ключевого слова var и когда его использовать (или опустить)?

Обратите внимание на объявление, что «Если вы находитесь в глобальной области, то нет никакой разницы».

Очевидно, что это не на 100% верно, учитывая мой рабочий пример.

Это странная логика или законная логика?


добавление краткого ответа на вопрос, который я узнал:

Благодаря Тиму (см. Ниже) ключ к моемунедоразумение не понимало этого (основополагающее для javascript)

var z;абсолютно ничего не делает, если z уже существует

Вот так выглядит это выражение в обоих случаях, если вы ошибочно полагаете, что "var z" всегда инициализируется.

Начиная слева,«var z» просто гарантирует, что z определен, но фактически не влияет на любое существующее значение, если оно уже существует.Затем справа, если z уже существует, он используется, если нет, переменная была только что объявлена ​​(но пуста), поэтому она не будет использоваться, но не выдаст ошибку.

Это отличностатья по этому виду задач и подъему в Javascript: http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

Большое спасибо Minitech и всем, кто тоже внес свой вклад!

Ответы [ 3 ]

10 голосов
/ 30 января 2012

Эффект правильный.var всегда будет объявлять свои «операнды» сразу, тогда как, когда вы не объявляете это, ваш скрипт пытается использовать неопределенную переменную и выдает ошибку.

Если вы находитесь в глобальной области видимости, выможет присвоить несуществующую переменную, и это будет иметь тот же эффект, что и ее объявление, что может быть плохой практикой.Конечно, в вашем случае это не определено.Это, как говорится, хотя это может быть из интеллектуального любопытства, вы бы никогда не написали бы

var z = z || [];

, потому что это не имеет смысла делать это.Скорее вы можете сделать:

if(!window.z) {
    window.z = [];
}

.Фактически, когда я объявляю вещи в глобальной области видимости (которая никогда не бывает ;)), я вместо этого использую window.<i>something</i>, потому что это делает мои намерения более ясными.

6 голосов
/ 30 января 2012

z = z || [] выбрасывает любую область (глобальную или нет), где нет z в цепочке областей.Причина этого заключается в том, что выражение сначала пытается извлечь значение существующей переменной с именем z с правой стороны, что является ошибкой, когда ее не существует.

Причина, по которой var z = z || [] не делаетВыдает ошибку, поскольку перед выполнением выражения создается переменная z (если она еще не существует). Этот эффект обычно известен как hoisting .

С другой стороны, присвоение значения неразрешенному идентификатору (например, z = 2) будет работать без ошибок в любой области (кроме строгого режима ECMAScript 5, который запрещает его и выбрасывает).Если идентификатор не может быть разрешен, он будет добавлен в качестве свойства конечного объекта в цепочке областей действия, который является глобальным объектом, что создает видимость создания глобальной переменной.

4 голосов
/ 30 января 2012

Вы можете назначить необъявленную переменную z = 123;однако вы не можете пытаться прочитать то, что делает z = z || [].

...