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

ПРИМЕЧАНИЕ. Этот вопрос был задан с точки зрения ECMAScript версии 3 или 5. Ответы могут устареть с появлением новых функций в выпуске ECMAScript 6.

Какова именно функция ключевого слова var в JavaScript и в чем разница между

var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;

а также

someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;

?

Когда бы вы использовали любой из них и почему / для чего он нужен?


person Alex    schedule 24.09.2009    source источник
comment
При объединении объявлений var в цепочку влияет ли на поведение ввод новой строки после запятой? var x = 1, y = 2, [return] z = 3;   -  person Alfabravo    schedule 20.11.2011
comment
Отсутствие использования var также оставляет вас незащищенными в случае, если выбранное вами имя переменной оказывается ранее определенной глобальной переменной. Смотрите мое путешествие горя здесь: stackoverflow.com/questions/16704014/   -  person Scott C Wilson    schedule 23.05.2013
comment
Сообщение в блоге meloncard @Ray Toal (определенно заслуживающее прочтения) перемещено на blog.safeshepherd.com/23/how-one-missing-var-ruined-our-launch   -  person Hephaestus    schedule 02.03.2014
comment
Никогда бы не подумал, что стихотворение может вдохновить меня на размышления о программной проблеме   -  person Félix Adriyel Gagnon-Grenier    schedule 15.03.2015
comment
Вместо этого используйте const и let! var - это не современный JS   -  person Gibolt    schedule 15.08.2017
comment
@Gibolt, но посмотрите на дату вопроса, это как-то несправедливо, чтобы сообщить об этом в вопросе 2009 года. Несмотря на то, что он по-прежнему действителен, как и в настоящее время, для удобства обслуживания существует множество не современного JS-кода.   -  person Andre Figueiredo    schedule 16.03.2018
comment
Надеюсь, что кто-то, читающий мой комментарий, который плохо знаком с JS (вероятно, если будет искать это), рано узнает. Тот факт, что существует несовременный код, не означает, что мы должны продолжать продвигать его как правильный ответ.   -  person Gibolt    schedule 16.03.2018
comment
Обратите внимание, что в современном JavaScript вы обычно должны использовать let вместо _2 _ (из-за различий в поведении let и var).   -  person Quentin    schedule 19.12.2019


Ответы (19)


Если вы находитесь в глобальном масштабе, особой разницы нет. Прочтите ответ Kangax для объяснения.

Если вы находитесь в функции, то var создаст локальную переменную, "no var" будет искать в цепочке областей видимости, пока не найдет переменную или не попадет в глобальную область видимости (в этот момент она создаст ее. ):

// These are both globals
var foo = 1;
bar = 2;

function()
{
    var foo = 1; // Local
    bar = 2;     // Global

    // Execute an anonymous function
    (function()
    {
        var wibble = 1; // Local
        foo = 2; // Inherits from scope above (creating a closure)
        moo = 3; // Global
    }())
}

Если вы не выполняете задание, вам нужно использовать var:

var x; // Declare x
person Greg    schedule 24.09.2009
comment
Неужели нет большой разницы == Разницы нет? - person Alex; 24.09.2009
comment
Ну вообще-то да, разница есть :) Важна ли эта разница - другой вопрос. См. Мой ответ ниже: stackoverflow.com/questions/1470488/ - person kangax; 25.09.2009
comment
Я думаю, что это может быть точка зрения Алекса, поэтому он написал это с использованием оператора равно! - person James Bedford; 13.09.2012
comment
Это как выстрелить в себя из рельсотрона ... Забудьте поставить 'var' перед переменной и закончите тем, что измените переменную где-нибудь в цепочке областей видимости ... Попробуйте убедить Java / C / Python /так далее. разработчик, что JavaScript стоит. Ха! Подводные камни C / C ++ по контрасту выглядят хорошо. Представьте, что вам нужно отлаживать JavaScript ... И, конечно, некоторые люди это делают. И так много кода (а не простого кода, заметьте) написано на JavaScript ... - person Albus Dumbledore; 24.02.2013
comment
Если вы находитесь в глобальной области видимости, разницы нет. ›› есть разница, которая объясняется в ответе ниже - person Max Koretskyi; 13.09.2013
comment
@Alex 0 == false, так что да, разницы нет == Разницы нет, но разницы нет! == Разницы нет - person Math chiller; 14.11.2013
comment
Если в строгом режиме, даже в глобальной области, вам нужно var, чтобы объявить это. - person Juan Mendes; 15.11.2013
comment
если вы 'use strict'; то вам следует использовать var. - person WarFox; 24.03.2014
comment
это важно, если вы хотите сохранить общедоступные API / частные члены шаблона модуля. понимание того, что var будет помещать объекты в локальную область видимости модуля, имеет важное значение. Спасибо за объяснение. Также следует отметить, что, если я прав, функция x () эквивалентна var x = function () и отличается от x = function () в отношении области видимости. - person ferr; 10.09.2014
comment
Большое спасибо. Я боролся с этим целую вечность, затем я прочитал эту строку: 'Если вы находитесь в функции, тогда var создаст локальную переменную, ни один var не будет искать цепочку областей видимости, пока не найдет переменную или не попадет в глобальную область ( в этот момент он создаст это) '- прекрасное объяснение, спасибо. - person developerbmw; 04.02.2015
comment
что вы имеете в виду, говоря о создании замыкания? - person NuWin; 31.07.2016
comment
Это большая разница: переменные, объявленные с помощью var, существуют до начала выполнения, а те, которые не существуют, пока не будет выполнен оператор, который их создает. Кроме того, те, которые объявлены с помощью var, не могут быть удалены, тогда как те, которые не являются удаляемыми свойствами глобального объекта. Кроме того, анонимная функция закрывает все внешние переменные, а не только глобальные (т. Е. Закрывает foo, bar и мычание. - person RobG; 07.11.2017
comment
См. Также stackoverflow.com/questions/38270470/ интересный пример более тонкой разницы между двумя объявлениями. - person Mihai Târnovan; 28.09.2018
comment
Фраза ... в этот момент будет создана имеет очень неоднозначную формулировку - мой вопрос все еще не решен. Эта точка связана с логическим потоком? (например, нигде не найдено, поэтому создается .. локально) Или точка связана с областью действия, в которой создается переменная? (например, переменная ищется до глобальной области, не найдена даже там, поэтому создана там). Не могли бы вы его немного перефразировать, пожалуйста? - person xakepp35; 21.10.2018
comment
Для кода C ++ int i=1; { cout<<i; int i=2; cout<<i; } cout<<i; вывод будет: 121. Это поведение без var или var? - person xakepp35; 21.10.2018

Есть разница.

var x = 1 объявляет переменную x в текущей области (также известной как контекст выполнения). Если объявление появляется в функции - объявляется локальная переменная; если он находится в глобальной области видимости - объявляется глобальная переменная.

x = 1, с другой стороны, просто присвоение собственности. Сначала он пытается разрешить x в цепочке областей видимости. Если он находит его где-нибудь в этой цепочке областей видимости, он выполняет присваивание; если он не находит x, только тогда он создает свойство x для глобального объекта (который является объектом верхнего уровня в цепочке областей видимости).

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

Разница между ними тонкая и может сбивать с толку, если вы не понимаете, что объявления переменных также создают свойства (только для объекта переменной) и что каждое свойство в Javascript (ну, ECMAScript) имеет определенные флаги, описывающие их свойства - ReadOnly, DontEnum и DontDelete.

Поскольку объявление переменной создает свойство с флагом DontDelete, разница между var x = 1 и x = 1 (при выполнении в глобальной области видимости) заключается в том, что первое - объявление переменной - создает свойство DontDelete'able, а второе - нет. Как следствие, свойство, созданное с помощью этого неявного присвоения, затем может быть удалено из глобального объекта, а первое свойство, созданное с помощью объявления переменной, не может быть удалено.

Но это, конечно, всего лишь теория, а на практике между ними еще больше различий из-за различных ошибок в реализациях (например, из IE).

Надеюсь, все это имеет смысл :)


[Обновление 2010/12/16]

В ES5 (ECMAScript 5; недавно стандартизованная 5-я редакция языка) есть так называемый «строгий режим» - языковой режим выбора, который немного меняет поведение незаявленных назначений. В строгом режиме присвоение необъявленному идентификатору является ReferenceError. Причиной этого было обнаружение случайных назначений, предотвращение создания нежелательных глобальных свойств. Некоторые из новых браузеров уже начали поддержку строгого режима. См., Например, мою таблицу совместимости.

person kangax    schedule 24.09.2009
comment
Если я правильно помню, мне кажется, я однажды нашел способ delete объявить переменную с помощью некоторого eval хака. Если я вспомню точный трюк, я опубликую здесь. - person Tower; 30.06.2011
comment
@Mageek Он может иметь дело с объявленными eval переменными, которые можно удалить. Я однажды написал сообщение в блоге об этом. - person kangax; 20.06.2012
comment
Немного не по теме, но упомянул об этом здесь для справки. let очень похож на var и поддерживается в Mozilla. Основное отличие состоит в том, что область видимости переменной var - это вся включающая функция, тогда как let ограничена ее блоком. - person mac; 01.10.2012
comment
@kangax, а что, если последние две строки примеров Алекса были смешаны: var someObject = {} и someObject.someProperty = 5? Станет ли someProperty глобальным, а объект, свойством которого он является, остается локальным? - person snapfractalpop; 28.11.2012
comment
Имя спецификации для того, что @kangax называет флагом DontDelete, - configurable (= false), вы можете прочитать об этом в отношении _ 2_ и _ 3_ - person Paul S.; 08.01.2014
comment
в некоторых версиях IE есть ошибка, позволяющая удалить объявление переменной в глобальной области видимости - person Shiala; 19.12.2014
comment
@Shiala Я припоминаю что-то в этом роде. Я думаю только с переменными, которые затеняют (имеют то же имя) глобальные встроенные модули, но я не уверен. - person kangax; 19.12.2014
comment
Я сейчас не нахожусь рядом с компьютером, но, если мне не изменяет память, я попробовал с var x = 0; и IE не помешал мне удалить его. - person Shiala; 19.12.2014
comment
Было бы неплохо увидеть дополнительное обновление этого ответа, в котором подробно описывается, как let влияет на вопрос OP. - person Snekse; 24.09.2015
comment
@Snekse let не влияет на x = 1 часть ответа, поэтому единственная разница заключается в var x = 1 и let x = 1. Это было много раз задокументировано во многих местах, но два основных отличия заключаются в том, что let имеет блочную область видимости и создает TDZ (временную мертвую зону), что означает, что вы не можете использовать или даже ссылаться на нее перед объявлением. - person kangax; 29.09.2015
comment
@kangax Я понял. Я просто говорю, что если кто-то, кто никогда даже не слышал о let, натолкнется на этот ответ, было бы хорошо просто упомянуть let и перейти на другой источник информации, чтобы они могли прочитать. - person Snekse; 29.09.2015

Сказать, что это разница между "локальным и глобальным", не совсем верно.

Лучше подумать об этом как о разнице между "местный и ближайший". Ближайший, безусловно, может быть глобальным, но так будет не всегда.

/* global scope */
var local = true;
var global = true;

function outer() {
    /* local scope */
    var local = true;
    var global = false;

    /* nearest scope = outer */
    local = !global;

    function inner() {
        /* nearest scope = outer */
        local = false;
        global = false;

        /* nearest scope = undefined */
        /* defaults to defining a global */
        public = global;
    }
}
person Jonathan Lonowski    schedule 24.09.2009
comment
Разве не ближайшая область outer, где вы определяете var global = false;? - person Snekse; 19.04.2013
comment
@Snekse: «ближайший» не применяется, если объявлено ‹code› var global = false; ‹/code›. В этом объявлении «global» помещается в область действия outer (), потому что в объявлении используется «var». Поскольку 'var' не используется в inner (), он изменит значение на следующем уровне выше, то есть external (). - person Mitch; 18.09.2015
comment
Интересно, изменится ли ваш комментарий, если вы измените эту строку на var global = local;, и в этом случае ближайшей областью действия local будет локальная внешняя область, которая активно определяется. Хотя это становится странным, если вы измените ту же строку на var global = global, и в этом случае ближайшая область видимости при поиске значения global будет на один уровень выше в области глобальной области окна. - person Snekse; 24.09.2015

Когда Javascript выполняется в браузере, весь ваш код окружается оператором with, например:

with (window) {
    //Your code
}

Дополнительная информация о with - MDN

Поскольку var объявляет переменную в текущей области, нет никакой разницы между объявлением var внутри окна и ее отсутствием вообще.

Разница возникает, когда вы находитесь не прямо в окне, например. внутри функции или внутри блока.

Использование var позволяет скрыть внешние переменные с одинаковыми именами. Таким образом вы можете имитировать «частную» переменную, но это уже другая тема.

Практическое правило - всегда использовать var, потому что в противном случае вы рискуете внести незаметные ошибки.

РЕДАКТИРОВАТЬ: После критики, которую я получил, я хотел бы подчеркнуть следующее:

  • var объявляет переменную в текущей области
  • Глобальная область видимости window
  • Отсутствие использования var неявно объявляет var в глобальной области (окне)
  • Объявление переменной в глобальной области (окне) с помощью var аналогично ее пропуску.
  • Объявление переменной в областях, отличных от окна, с использованием var - не то же самое, что объявление переменной без var
  • Всегда объявляйте var явно, потому что это хорошая практика
person kentaromiura    schedule 24.09.2009
comment
Я не голосовал против вас, но объем, вероятно, лучше слова, чем окно. Все твои объяснения немного тупые. - person Robert Harvey; 25.09.2009
comment
Я просто называю вещи своим именем, вы хотите называть это глобальной областью видимости, это нормально, но на стороне клиента, по соглашению, является объект окна, это последний элемент цепочки областей видимости, поэтому вы можете вызывать каждую функцию и каждый объект в окне без окна записи. - person kentaromiura; 25.09.2009
comment
+1 Это действительно хорошее объяснение - я раньше не слышал, чтобы проблема var / no var создавалась так (без каламбура). - person doug; 10.04.2012
comment
Большая часть этого ответа устарела с let в ES6. - person Evan Carroll; 21.01.2014
comment
@EvanCarroll Этот ответ также технически неверен, поскольку опускание var не объявляет какую-либо переменную, вместо этого он создает удаляемое свойство для глобального объекта, кроме того, при использовании строгого режима ES5 большая часть ответа, очевидно, неверна, также пусть даже не было рассматривается в этом ответе, поскольку во время вопроса не было никакой ссылки на версию javascript (добавленную вчера), что означает, что стандартом ссылки (в то время) было ECMA 262 3rd Edition. - person kentaromiura; 22.01.2014
comment
Оператор весь ваш код окружен оператором with явно неверен. Если бы это было так, имена переменных были бы разрешены в объекте window перед локальной областью. - person RobG; 07.11.2017

Всегда используйте ключевое слово var для объявления переменных. Почему? Хорошая практика кодирования сама по себе должна быть достаточной причиной, но ее отсутствие означает, что она объявлена ​​в глобальной области (такая переменная называется «подразумеваемой» глобальной). Дуглас Крокфорд рекомендует никогда не использовать подразумеваемые глобальные переменные и согласно Рекомендации Apple по кодированию JavaScript :

Любая переменная, созданная без ключевого слова var, создается в глобальной области и не собирается сборщиком мусора при возврате функции (потому что она не выходит за пределы области видимости), что дает возможность утечки памяти.

person Steve Harrison    schedule 24.09.2009
comment
Хорошая практика кодирования никогда не должна быть достаточной причиной. Некоторые парни в Интернете сказали, что так должен выглядеть мой код. Это даже менее верно, чем сказал мой учитель, если только кто-то хотя бы смутно не понимает причину этого правила. - person cHao; 24.05.2013
comment
@cHao Я думаю, что good coding practice всегда является достаточным основанием, если это рекомендованная передовая практика, каковым является и несколько авторов Javascript. - person Chris S; 03.01.2014
comment
@ChrisS: Нет, хорошая практика кодирования сама по себе не является причиной. Важна причина, что это считается хорошей практикой. Если эти авторы не скажут вам, почему они рекомендуют это, их рекомендация не имеет никакого значения. Если вы не согласны с причинами, то можете счесть это плохим советом. И если вы последуете за ним, даже не спросив почему, так и начнется карго-культизм. - person cHao; 03.01.2014

Вот неплохой пример того, как вы можете попасть в ловушку, если не объявляете локальные переменные с помощью var:

<script>
one();

function one()
{
    for (i = 0;i < 10;i++)
    {
        two();
        alert(i);
    }
}

function two()
{
    i = 1;
}
</script>

(i сбрасывается на каждой итерации цикла, поскольку он объявляется не локально в цикле for, а глобально) в конечном итоге приводит к бесконечному циклу

person Chris S    schedule 24.09.2009
comment
Ой! Я могу представить себе все ошибки, которые могли быть вызваны этой опечаткой. - person BonsaiOak; 13.10.2014
comment
Мне любопытно, почему вы передаете i в качестве аргумента функции two ()? (внутри цикла for) это избыточно? - person kalin; 03.10.2016
comment
Аргумент игнорируется в функции two (), инкапсулированной в функцию one (), поскольку функция two () была определена без параметра. Вы совершенно правы, это не нужно, потому что это не играет роли. - person KK.; 24.02.2017
comment
Ошибка или особенность? - person TheMaster; 25.08.2019

Я бы сказал, что в большинстве ситуаций лучше использовать var.

Локальные переменные всегда быстрее, чем переменные в глобальной области видимости.

Если вы не используете var для объявления переменной, переменная будет в глобальной области видимости.

Для получения дополнительной информации вы можете выполнить поиск «JavaScript цепочки областей видимости» в Google.

person Billy    schedule 24.09.2009
comment
Если вы объявляете переменную с помощью ключевого слова var, она будет создана во время выполнения, не должна ли она быть медленнее? Потому что другой создается во время синтаксического анализа. - person Barış Velioğlu; 14.08.2012
comment
@RyuKaplan - эй, это правда? Я попробовал поискать в Google и не смог получить никакой информации по этому поводу! Есть ли у вас авторитетный источник для этого утверждения? Спасибо - person mike rodent; 12.04.2013
comment
@RyuKaplan Парсинг / компиляция отличается от фактического запуска кода. - person gcampbell; 08.07.2016

Не используйте var!

var был способом объявления переменной до ES6. Мы сейчас в будущем, и вы должны заниматься кодированием как таковым.

Используйте const и let

const следует использовать в 95% случаев. Это делает так, чтобы ссылка на переменную не могла измениться, поэтому свойства массива, объекта и узла DOM могут измениться и, вероятно, должны быть const.

let следует использовать для любой переменной, которая должна быть переназначена. Это включает в себя цикл for. Если вы когда-нибудь напишете varName = после инициализации, используйте let.

Оба имеют область видимости на уровне блока, как и ожидалось в большинстве других языков.

person Gibolt    schedule 15.08.2017
comment
Замените все ваши 'var' на 'const' (замените все). Вы быстро заметите, где находятся ваши переназначенные переменные. Если у вас их слишком много, вы, вероятно, кодируете антишаблонный код: большинство переназначаемых переменных могут быть встроены в замыкания или как свойства объекта. Если у вас их несколько: используйте для них «let». Наконец, будьте осторожны, если некоторые переменные вообще не помечены с помощью 'var', они останутся необъявленными и все еще присутствуют в глобальном пространстве. Что касается комментария @Gibolt «внутри цикла for», также рекомендуется избегать таких циклов в 95% случаев ;-): методы массивов - это здорово. - person allez l'OM; 21.10.2018
comment
Говоря, что const следует использовать в 95% случаев, кажется, что мы уходим от хорошей практики к догме. - person Agamemnus; 28.12.2018

другое отличие, например

var a = a || [] ; // works 

в то время как

a = a || [] ; // a is undefined error.
person Pranay Warke    schedule 09.08.2013
comment
Не могли бы вы объяснить, почему это работает, если переменная определена с помощью var, а переменная не определена с помощью var? Создается ли переменная до оценки правой части присваивания в случае var? - person matt; 05.12.2013
comment
@Lucek, потому что var a поднимается в верхнюю часть области и устанавливается в значение null, которое объявляет, но не инициализирует переменную, тогда в назначении у вас есть ссылка на неопределенную нулевую переменную, которая оценивается как false, и устанавливает присвоение []. В последнем случае у вас есть присвоение свойству a свойства a. Вы можете назначить несуществующее свойство - создав его при назначении, но вы не можете читать из несуществующего свойства, не получив ReferenceError. - person Evan Carroll; 20.01.2014
comment
@EvanCarroll: он поднимается на вершину области видимости и получает значение undefined вместо null. - person Mithun Satheesh; 25.09.2014

Использование var всегда является хорошей идеей, чтобы переменные не загромождали глобальную область видимости, а переменные не конфликтовали друг с другом, вызывая нежелательную перезапись.

person kevinji    schedule 04.04.2011

Без var - глобальная переменная.

Настоятельно рекомендуется ВСЕГДА использовать оператор var, потому что инициализация глобальной переменной в локальном контексте - зло. Но, если вам нужен этот подвох, вы должны написать комментарий в начале страницы:

/* global: varname1, varname2... */
person Anatoliy    schedule 24.09.2009

Это пример кода, который я написал для вас, чтобы вы поняли эту концепцию:

var foo = 5; 
bar = 2;     
fooba = 3;

// Execute an anonymous function
(function() {    
    bar = 100;             //overwrites global scope bar
    var foo = 4;           //a new foo variable is created in this' function's scope
    var fooba = 900;       //same as above
    document.write(foo);   //prints 4
    document.write(bar);   //prints 100
    document.write(fooba); //prints 900
})();

document.write('<br/>');
document.write('<br/>');
document.write(foo);       //prints 5
document.write(bar);       //prints 100
document.write(fooba);     //prints 3
person Community    schedule 27.10.2013
comment
Функция ни в коем случае не анонимна. На самом деле, он назван так явно, насколько это возможно. - person Ingo Bürk; 23.01.2014
comment
Благодарим вас за редактирование вашего ответа в ответ на комментарий Инго Бюрка, чтобы сделать анонимную функцию фактически анонимной. - person Dave Burton; 09.09.2016

@Chris S привел хороший пример, демонстрирующий практическую разницу (и опасность) между var и no var. Вот еще один, который я считаю особенно опасным, потому что разница видна только в асинхронной среде, поэтому она может легко проскользнуть во время тестирования.

Как и следовало ожидать, следующий фрагмент кода выводит ["text"]:

function var_fun() {
  let array = []
  array.push('text')
  return array
}

console.log(var_fun())

То же самое и со следующим фрагментом (обратите внимание на отсутствующий let перед array):

function var_fun() {
  array = []
  array.push('text')
  return array
}

console.log(var_fun())

Асинхронное выполнение обработки данных по-прежнему дает тот же результат с одним исполнителем:

function var_fun() {
  array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

var_fun().then(result => {console.log(result)})

Но ведет себя по-разному с несколькими:

function var_fun() {
  array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

[1,2,3].forEach(i => {
  var_fun().then(result => {console.log(result)})
})

Однако с помощью let:

function var_fun() {
  let array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

[1,2,3].forEach(i => {
  var_fun().then(result => {console.log(result)})
})

person thisismydesign    schedule 29.12.2017
comment
Спасибо за пример @thisismydesign! Что касается последних двух примеров, почему предпоследний пример регистрирует массив из 3 элементов с текстом, написанным трижды, тогда как последний пример регистрирует текст только один раз для каждого элемента в массиве? (Я понимаю, что последний объявляет массив как переменную и поэтому находится в локальной области видимости, тогда как в предпоследнем примере это опускается, что делает массив частью подразумеваемой глобальной области.) Но почему как это влияет на результат? Это потому, что forEach i выполняет итерацию по функции и всем глобальным переменным? - person Brad Ahrens; 22.09.2019

Как кто-то пытается этому научиться, я вижу это так. Приведенные выше примеры могут быть слишком сложными для новичка.

Если вы запустите этот код:

var local = true;
var global = true;


function test(){
  var local = false;
  var global = false;
  console.log(local)
  console.log(global)
}

test();

console.log(local);
console.log(global);

Вывод будет выглядеть так: false, false, true, true.

Поскольку он видит переменные в функции отдельно от тех, которые находятся за ее пределами, отсюда и термин «локальная переменная», и это произошло потому, что мы использовали var в присвоении. Если вы уберете переменную в функции, теперь она будет выглядеть так:

var local = true;
var global = true;


function test(){
  local = false;
  global = false;
  console.log(local)
  console.log(global)
}

test();

console.log(local);
console.log(global);

Выходные данные - ложь, ложь, ложь, ложь

Это потому, что вместо того, чтобы создавать новую переменную в локальной области или функции, он просто использует глобальные переменные и переназначает их на false.

person Danrex    schedule 01.10.2016

Я вижу, что люди сбиты с толку, объявляя переменные с var или без него, внутри или вне функции. Вот подробный пример, который проведет вас через эти шаги:

См. приведенный ниже скрипт в действии здесь, на jsfiddle

a = 1;// Defined outside the function without var
var b = 1;// Defined outside the function with var
alert("Starting outside of all functions... \n \n a, b defined but c, d not defined yet: \n a:" + a + "\n b:" + b + "\n \n (If I try to show the value of the undefined c or d, console.log would throw 'Uncaught ReferenceError: c is not defined' error and script would stop running!)");

function testVar1(){
    c = 1;// Defined inside the function without var
    var d = 1;// Defined inside the function with var
    alert("Now inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);

    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;

    alert("After added values inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};


testVar1();
alert("Run the 1. function again...");
testVar1();

function testVar2(){
    var d = 1;// Defined inside the function with var
    alert("Now inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);

    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;

    alert("After added values inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};

testVar2();

alert("Now outside of all functions... \n \n Final Values: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n You will not be able to see d here because then the value is requested, console.log would throw error 'Uncaught ReferenceError: d is not defined' and script would stop. \n ");
alert("**************\n Conclusion \n ************** \n \n 1. No matter declared with or without var (like a, b) if they get their value outside the function, they will preserve their value and also any other values that are added inside various functions through the script are preserved.\n 2. If the variable is declared without var inside a function (like c), it will act like the previous rule, it will preserve its value across all functions from now on. Either it got its first value in function testVar1() it still preserves the value and get additional value in function testVar2() \n 3. If the variable is declared with var inside a function only (like d in testVar1 or testVar2) it will will be undefined whenever the function ends. So it will be temporary variable in a function.");
alert("Now check console.log for the error when value d is requested next:");
alert(d);

Заключение

  1. Независимо от того, объявлены они с var или без него (например, a, b), если они получают свое значение вне функции, они сохранят свое значение, а также любые другие значения, которые добавляются внутри различных функций через скрипт.
  2. Если переменная объявлена ​​без var внутри функции (например, c), она будет действовать как предыдущее правило, с этого момента она будет сохранять свое значение во всех функциях. Либо он получил свое первое значение в функции testVar1 (), он все еще сохраняет значение и получает дополнительное значение в функции testVar2 ()
  3. Если переменная объявлена ​​с помощью var только внутри функции (например, d в testVar1 или testVar2), она будет неопределенной при каждом завершении функции. Таким образом, это будет временная переменная в функции.
person Tarik    schedule 20.11.2016
comment
Спасибо, что нашли время создать пример для демонстрации этой темы. В приведенном выше коде отсутствует часть ниже, поэтому вы можете изменить свой ответ: a = 1; // Определено вне функции без var var b = 1; // Определено вне функции с помощью var alert (Начиная с всех функций. .. \ n \ na, b определены, но c, d еще не определены: \ na: + a + \ nb: + b + \ n \ n (Если я попытаюсь показать значение неопределенных c или d, console. log выдаст ошибку «Uncaught ReferenceError: c is not defined» и скрипт перестанет работать!)); - person Sankofa; 11.10.2018

Внутри кода вы, если вы используете переменную без использования var, тогда происходит автоматическое размещение var var_name в глобальной области, например:

someFunction() {
    var a = some_value; /*a has local scope and it cannot be accessed when this
    function is not active*/
    b = a; /*here it places "var b" at top of script i.e. gives b global scope or
    uses already defined global variable b */
}
person Akash Arora    schedule 13.08.2013

Помимо проблемы с областями, некоторые люди также упоминают подъем, но никто не привел примера. Вот один для глобального масштаба:

console.log(noErrorCase);
var noErrorCase = "you will reach that point";

console.log(runTimeError);
runTimeError = "you won't reach that point";

person deathangel908    schedule 05.09.2019

Без использования «var» переменные можно определять только при установке значения. Например:

my_var;

не может работать в глобальной области или любой другой области. Оно должно иметь значение вроде:

my_var = "value";

С другой стороны, вы можете определить vaiable like;

var my_var;

Его значение undefined (его значение не null и, что интересно, не равно null).

person umut    schedule 27.04.2014
comment
my_var; на самом деле является допустимым выражением. - person lexicore; 27.11.2014
comment
Это действительное утверждение, если переменная определена ранее. В противном случае выдается ошибка ... не определено. - person umut; 27.11.2014
comment
Это допустимый оператор независимо от того, была ли ранее определена переменная или нет. :) Правильный оператор может вызвать ошибку, он не делает недействительным оператор. - person lexicore; 27.11.2014
comment
Я смущен этим. Что является действительным заявлением? А вы можете привести мне пример неверного утверждения? - person umut; 27.11.2014
comment
Придется извиниться - слишком много грамматики ECMAScript в последнее время. my_var; является допустимым выражением. /my_var; было бы недопустимым заявлением. Но, как я уже сказал, это грамматическая казуистика, прошу прощения, мой комментарий был на самом деле неуместным. - person lexicore; 27.11.2014

Вам следует использовать ключевое слово var, если вы не собираетесь прикреплять переменную к объекту окна в браузере. Вот ссылка, объясняющая область видимости и разница между глобальным и локальным охватом с ключевым словом var и без него.

Когда переменные определяются без использования ключевого слова var, это выглядит как простая операция «присваивания».

Когда значение присваивается переменной в javascript, интерпретатор сначала пытается найти «объявление переменной» в том же контексте / области, что и назначение. Когда интерпретатор выполняет dummyVariable = 20, он ищет объявление dummyVariable в начале функции. (Поскольку все объявления переменных перемещаются в начало контекста интерпретатором javascript, и это называется подъемом)

Вы также можете ознакомиться с подъемом в javascript

person S Khurana    schedule 12.12.2016