ПРИМЕЧАНИЕ. Этот вопрос задавался с точки зрения 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;
?
Когда вы используете один из них и почему/что он делает?
Если вы находитесь в глобальной области, то нет большой разницы. Прочтите ответ 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
Есть разница.
var x = 1
объявляет переменную x
в текущей области (также как контекст исполнения). Если объявление появляется в функции - объявляется локальная переменная; если он в глобальной области действия - объявлена глобальная переменная.
x = 1
, с другой стороны, является просто присвоением свойства. Сначала он пытается разрешить x
по цепочке цепей. Если он находит его где-либо в этой цепочке видимости, он выполняет назначение; если он не находит x
, только тогда он создает свойство x
для глобального объекта (который является объектом верхнего уровня в цепочке областей видимости).
Теперь обратите внимание, что он не объявляет глобальную переменную, он создает глобальное свойство.
Разница между двумя является тонкой и может быть запутанной, если вы не понимаете, что объявления переменных также создают свойства (только для объекта Variable) и что каждое свойство в Javascript (хорошо, ECMAScript) имеет определенные флаги, которые описывают их свойства - ReadOnly, DontEnum и DontDelete.
Поскольку объявление переменной создает свойство с флагом DontDelete, разница между var x = 1
и x = 1
(при выполнении в глобальной области) заключается в том, что первое объявление одной переменной - создает свойство DontDelete'able, а последнее - "т. Как следствие, свойство, созданное с помощью этого неявного присваивания, затем может быть удалено из глобального объекта, а прежний - тот, который создан через объявление переменной - не может быть удален.
Но это просто теория, и на практике существуют еще большие различия между двумя, из-за различных ошибок в реализациях (например, из IE).
Надеюсь, что все это имеет смысл:)
[Обновить 2010/12/16]
В ES5 (ECMAScript 5, недавно стандартизованный 5-й выпуск языка) существует так называемый "строгий режим" - режим выбора языка, который слегка изменяет поведение незадекларированных назначений. В строгом режиме присвоение необъявленного идентификатора является ReferenceError. Обоснованием для этого было уловить случайные назначения, предотвращая создание нежелательных глобальных свойств. Некоторые из новых браузеров уже начали откатывать поддержку строгого режима. См., Например, мою таблицу сопоставлений.
delete
переменную, объявленную var, с помощью некоторого взлома eval
. Если я помню точную уловку, я отправлю здесь.
Говорить, что разница между локальными и глобальными "не совсем точна.
Лучше подумать об этом как о различии между локальным и ближайшим. Ближайший, безусловно, может быть глобальным, но это не всегда так.
/* 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;
}
}
outer
где вы определяете var global = false;
?
Когда Javascript выполняется в браузере, весь ваш код окружен оператором with, например:
with (window) {
//Your code
}
Дополнительная информация о with
- MDN
Так как var
объявляет переменную в текущей области, нет разницы между объявлением var
внутри окна и не объявлением вообще.
Разница возникает, когда вы не находитесь непосредственно внутри окна, например. внутри функции или внутри блока.
Использование var
позволяет скрыть внешние переменные с тем же именем. Таким образом, вы можете моделировать переменную "private", но эту другую тему.
Правило большого пальца - всегда использовать var
, потому что иначе вы рискуете ввести тонкие ошибки.
EDIT: После критики, которую я получил, я хотел бы подчеркнуть следующее:
var
объявляет переменную в текущей областиwindow
var
неявно объявляет var
в глобальной области (окне)var
аналогично исключению.var
- это не одно и то же как объявление переменной без var
var
явно, потому что это хорошая практикаВы всегда должны использовать ключевое слово var
для объявления переменных. Зачем? Хорошая практика кодирования должна быть достаточной причины сама по себе, но объявление переменной без ключевого слова var
означает, что она объявлена в области global (такая переменная, как это называется "подразумеваемая" глобальная), Douglas Crockford рекомендует никогда не использовать подразумеваемые глобальные переменные, и согласно Правилам кодирования Apple JavaScript:
Любая переменная, созданная без
var
ключевое слово создается в глобальном масштабе и это не сбор мусора, когда функция возвращает (потому что она не делает выходят за рамки), представляя возможность утечки памяти.
Итак, короче говоря, всегда объявляйте переменные, используя ключевое слово var
.
good coding practice
всегда является достаточной причиной, если это рекомендуемая лучшая практика, которой пользуются несколько авторов Javascript.
Вот неплохой пример того, как вы можете поймать, не объявляя локальные переменные с var
:
<script>
one();
function one()
{
for (i = 0;i < 10;i++)
{
two();
alert(i);
}
}
function two()
{
i = 1;
}
</script>
(i
есть reset на каждой итерации цикла, так как он не объявлен локально в цикле for
, но глобально), что в конечном итоге приводит к бесконечному циклу
Я бы сказал, что лучше использовать var
в большинстве ситуаций.
Локальные переменные всегда быстрее переменных в глобальной области.
Если вы не используете var
, чтобы объявить переменную, переменная будет в глобальной области.
Для получения дополнительной информации вы можете выполнить поиск "JavaScript с цепочкой цепей" в Google.
другое различие например
var a = a || [] ; // works
while
a = a || [] ; // a is undefined error.
var
?
var a
поднимается до верхней части области и устанавливается в значение null, которое объявляет, но не инициализирует переменную, тогда в присваивании у вас есть ссылка на неопределенную переменную null, которая оценивается как false, и установите присваивание равным []
, В последнем у вас есть присваивание свойству a
свойства a
. Вы можете присвоить несуществующему свойству - создавая его по присваиванию, но вы не можете читать из несуществующего свойства без получения ReferenceError
.
Использование var
всегда является хорошей идеей для предотвращения перегруппировки переменных из глобальной области и переменных, которые конфликтуют друг с другом, что приводит к нежелательной перезаписке.
Без var
- глобальной переменной.
Настоятельно рекомендуется ВСЕГДА использовать оператор var
, поскольку глобальная переменная init в локальном контексте - зло. Но, если вам нужен этот грязный трюк, вы должны написать комментарий в начале страницы:
/* global: varname1, varname2... */
var
! var
был способом pre-ES6 для объявления переменной. Мы сейчас в будущем, и вы должны быть кодированием как таковым.
const
и let
const
следует использовать в 95% случаев. Это делает так, чтобы переменная-ссылка не могла измениться, поэтому свойства массива, объекта и DOM node могут меняться и, вероятно, должны быть const
.
let
следует использовать для любой переменной, ожидающей переназначения. Это включает в себя цикл for. Если вы пишете varName =
после инициализации, используйте let
.
Оба имеют область охвата уровня блока, как и ожидалось на большинстве других языков.
Это пример кода, который я написал для вас, чтобы понять эту концепцию:
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 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
Внутри кода вы, если используете переменную без использования 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 */
}
@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)})
})
Использование пусть однако:
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)})
})
Вам следует использовать ключевое слово var, если вы не намерены привязывать переменную к объекту window в браузере. Здесь ссылка, которая объясняет область видимости и разницу между областью определения glocal и локальным охватом с помощью ключевого слова wihtout var.
Когда переменные определяются без использования ключевого слова var, похоже, что это простая операция присваивания.
Когда значение присваивается переменной в javascript, интерпретатор сначала пытается найти "объявление переменной" в том же контексте/области, что и назначение. Когда интерпретатор выполняет dummyVariable = 20
, он ищет декларацию dummyVariable в начале функции.
(Так как все объявления Variable перемещаются в начало контекста с помощью javascript-интерпретатора, и это называется подъемом)
Вы также можете посмотреть подъем в javascript
Я вижу, что люди запутываются при объявлении переменных с или без var и внутри или вне функции. Вот подробный пример, который поможет вам выполнить следующие шаги:
См. ниже script в действии здесь, в 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);
Заключение
- Независимо от того, объявлены с var или нет var (например, a, b), если они получают свое значение вне функции, они сохраняют свое значение, а также любые другие значения, которые добавляются внутри различных функций через script, сохраняются.
- Если переменная объявлена без var внутри функции (например, c), она будет действовать как предыдущее правило, она сохранит свое значение во всех функциях с этого момента. Либо он получил свое первое значение в функции testVar1(), он все еще сохраняет значение и получает дополнительное значение в функции testVar2()
- Если переменная объявлена с var внутри функции только (например, d в testVar1 или testVar2), она будет undefined всякий раз, когда заканчивается функция. Таким образом, это будет временная переменная в функции.
Как кто-то пытается узнать это, я вижу это. Вышеприведенные примеры были, возможно, слишком сложными для новичка.
Если вы запустите этот код:
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 в функции, чтобы она теперь читалась следующим образом:
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, false, false, false
Это связано с тем, что вместо создания новой переменной в локальной области или функции она просто использует глобальные переменные и переназначает их на false.
Без использования переменных "var" можно определить только при установке значения. В примере:
my_var;
не может работать в глобальной области или в любой другой области. Он должен быть со значением вроде:
my_var = "value";
С другой стороны, вы можете определить vaiable like;
var my_var;
Его значение undefined
(его значение не null
и оно не равно null
).
my_var;
на самом деле является действительным выражением выражения.