ПРИМЕЧАНИЕ . Этот вопрос был задан с точки зрения 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;
?
Когда бы вы использовали один из них, и почему / что он делает?
Ответы:
Если вы находитесь в глобальном масштабе, то особой разницы нет. Прочитайте ответ Кангакса для объяснения
Если вы находитесь в функции, то
var
создадите локальную переменную, «no var» будет искать цепочку областей видимости, пока не найдет переменную или не достигнет глобальной области видимости (в этот момент она ее создаст):Если вы не выполняете задание, вам нужно использовать
var
:источник
Там разница .
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-я редакция языка) существует так называемый «строгий режим» - языковой режим opt-in, который немного меняет поведение необъявленных назначений. В строгом режиме присвоение необъявленного идентификатора является ReferenceError . Основанием для этого было отловить случайные присваивания, предотвращающие создание нежелательных глобальных свойств. Некоторые из новых браузеров уже начали активную поддержку строгого режима. Смотрите, например, мою таблицу сравнения .
источник
delete
переменную, объявленную var, с некоторымeval
взломом. Если я помню точную уловку, я отправлю здесь.var someObject = {}
аsomeObject.someProperty = 5
? Станет лиsomeProperty
глобальным, а объект, к которому он принадлежит, останется локальным?false
) , вы можете прочитать об этом в отношенииObject.defineProperty
иObject.getOwnPropertyDescriptor
Сказать, что разница между « локальным и глобальным » не совсем точно.
Возможно, лучше думать об этом как о разнице между « местным и ближайшим ». Ближайший может быть глобальным, но это не всегда так.
источник
outer
где вы определяетеvar global = false;
?var global = local;
в этом случае ближний объем локального будет «локальным» внешним объемом, который активно определяется. Хотя становится странным, если вы измените эту же строку, иvar global = global
в этом случае ближайшая область при поиске значенияglobal
будет выше уровня глобальной области окна.Когда Javascript выполняется в браузере, весь ваш код окружен оператором with, например:
Более подробная информация о
with
- MDNТак как
var
объявляет переменную в текущей области видимости , нет никакой разницы между объявлениемvar
внутри окна и не объявлением его вообще.Разница возникает, когда вы находитесь не непосредственно внутри окна, например, внутри функции или внутри блока.
Использование
var
позволяет скрыть внешние переменные с одинаковыми именами. Таким образом, вы можете смоделировать «приватную» переменную, но это уже другая тема.Эмпирическое правило всегда следует использовать
var
, потому что в противном случае вы рискуете внести незначительные ошибки.РЕДАКТИРОВАТЬ: После того, как я получил критику, я хотел бы подчеркнуть следующее:
var
объявляет переменную в текущей области видимостиwindow
var
неявно объявляетvar
в глобальной области видимости (окно)var
того же, что и ее пропуск.var
- это не то же самое, что объявление переменной безvar
var
явно, потому что это хорошая практикаисточник
let
в ES6.Всегда используйте
var
ключевое слово для объявления переменных. Почему? Хорошая практика кодирования должна быть достаточной причиной сама по себе, но ее опущение означает, что она объявлена в глобальной области видимости (такая переменная называется «подразумеваемой» глобальной). Дуглас Крокфорд рекомендует никогда не использовать подразумеваемые глобальные переменные , и согласно Руководству Apple по кодированию JavaScript :источник
good coding practice
это всегда достаточная причина, если это рекомендуемая лучшая практика, которой пользуются несколько авторов Javascript.Вот довольно хороший пример того, как вы можете оказаться не объявив локальные переменные с помощью
var
:(
i
сбрасывается на каждой итерации цикла, так как он не объявляется локально вfor
цикле, но глобально), что в итоге приводит к бесконечному циклуисточник
Я бы сказал, что лучше использовать
var
в большинстве ситуаций.Локальные переменные всегда быстрее, чем переменные в глобальной области видимости.
Если вы не используете
var
для объявления переменной, переменная будет в глобальной области видимости.Для получения дополнительной информации вы можете выполнить поиск «JavaScript цепочки областей действия» в Google.
источник
Не используйте
var
!var
был до-ES6 способ объявить переменную. Мы сейчас в будущем , и вы должны писать код как таковой.Используйте
const
иlet
const
следует использовать в 95% случаев. Это делает так, чтобы ссылка на переменную не могла изменяться, поэтому свойства массива, объекта и узла DOM могут изменяться и, вероятно, должны быть такимиconst
.let
следует использовать для любой переменной, ожидающей переназначения. Это включает в себя цикл for. Если вы когда-нибудь пишетеvarName =
за инициализацией, используйтеlet
.Оба имеют область видимости на уровне блоков, как и ожидалось в большинстве других языков.
источник
другая разница, например
пока
источник
var
?var a
он поднимается в верхнюю часть области и устанавливается в значение null, которое объявляет, но не инициализирует переменную, тогда в присваивании у вас есть ссылка на неопределенную переменную null, которая оценивается как false, и присваивает присвоение значение[]
. В последнем у вас есть назначение на имуществоa
собственностиa
. Вы можете присвоить свойству, которое не существует, - создавая его по назначению, но вы не можете прочитать из свойства, которое не существует, без полученияReferenceError
вашего ответа.Использование
var
- это всегда хорошая идея, чтобы не допустить загромождения переменных глобальной области видимости, а также того, что переменные конфликтуют друг с другом, вызывая нежелательную перезапись.источник
Без
var
- глобальная переменная.Настоятельно рекомендуется ВСЕГДА использовать
var
оператор, потому что глобальная переменная init в локальном контексте - это зло. Но, если вам нужен этот подвох, вы должны написать комментарий в начале страницы:источник
Это пример кода, который я написал для вас, чтобы понять эту концепцию:
источник
@Chris S привел хороший пример, демонстрирующий практическую разницу (и опасность) между
var
и нетvar
. Вот еще один, я считаю этот особенно опасным, потому что разница видна только в асинхронной среде, поэтому она может легко проскользнуть во время тестирования.Как и следовало ожидать следующие фрагменты вывода
["text"]
:Как и следующий фрагмент (обратите внимание на отсутствующий
let
ранееarray
):Выполнение манипулирования данными в асинхронном режиме по-прежнему дает тот же результат с одним исполнителем:
Но ведет себя по-разному с несколькими:
Используя let однако:
источник
Как кто-то пытается узнать это, вот как я это вижу. Приведенные выше примеры были, возможно, слишком сложными для начинающего.
Если вы запустите этот код:
Вывод будет выглядеть как: ложь, ложь, правда, правда
Потому что он видит переменные в функции отдельно от тех, которые находятся за ее пределами, отсюда и термин локальная переменная, и это было потому, что мы использовали var в присваивании. Если вы уберете переменную в функции, она будет выглядеть так:
Выход ложный, ложный, ложный, ложный
Это потому, что вместо создания новой переменной в локальной области или функции она просто использует глобальные переменные и переназначает их на false.
источник
Я вижу, что люди смущены, когда объявляют переменные с или без var и внутри или вне функции. Вот глубокий пример, который проведет вас через эти шаги:
Смотрите скрипт ниже в действии здесь на jsfiddle
источник
Внутри кода вы, если вы используете переменную без использования var, то происходит автоматическое изменение var var_name в глобальной области видимости, например:
источник
Помимо вопроса о прицеле, некоторые люди также упоминают подъем , но никто не привел пример. Вот один для глобальной области видимости:
источник
Без использования «var» переменные можно определять только при заданном значении. В примере:
не может работать в глобальной области или любой другой области . Это должно быть со значением, как:
С другой стороны, вы можете определить vaiable как;
Его значение равно
undefined
(его значение не равноnull
и оно не равноnull
интересно).источник
my_var;
на самом деле является действительным выражением оператора.my_var;
является допустимым выражением выражения ./my_var;
будет неверным утверждением. Но, как я уже сказал, это грамматическая казуистика, извиняюсь, мой комментарий был на самом деле неуместным.Вы должны использовать ключевое слово var, если только вы не собираетесь прикреплять переменную к объекту окна в браузере. Вот ссылка, которая объясняет область видимости и разницу между глобальной областью видимости и локальной областью видимости с и без ключевого слова var.
Когда переменные определяются без использования ключевого слова var, это выглядит как простая операция «присваивания».
Когда значение присваивается переменной в javascript, интерпретатор сначала пытается найти «объявление переменной» в том же контексте / области, что и назначение. Когда переводчик выполняет
dummyVariable = 20
, он ищет объявление dummyVariable в начале функции. (Поскольку все объявления переменных перемещаются в начало контекста интерпретатором javascript, это называется подъемом)Вы также можете посмотреть на подъем в JavaScript
источник