Jaki jest cel słowa kluczowego var i kiedy należy go użyć (lub pominąć)?

Uwaga: to pytanie zostało zadane z punktu widzenia ECMAScript w wersji 3 lub 5. Odpowiedzi mogą stać się nieaktualne wraz z wprowadzeniem nowych funkcji w wydaniu ECMAScript 6.

Jaka jest dokładnie funkcja słowa kluczowego var w JavaScript i jaka jest różnica między

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

I

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

?

Kiedy używasz obu i dlaczego / co to robi?

Author: Peter Mortensen, 2009-09-24

18 answers

Jeśli jesteś w zasięgu globalnym, to nie ma dużej różnicy. Przeczytaj odpowiedź Kangaxa na Wyjaśnienie

If you 're in a function then var spowoduje utworzenie zmiennej lokalnej, "no var" będzie szukał łańcucha zakresu, aż znajdzie zmienną lub trafi w globalny zakres (w którym to momencie go utworzy):

// 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
    }())
}

Jeśli nie wykonujesz zadania, musisz użyć var:

var x; // Declare x
 1267
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-08 22:05:04

Jest różnica .

var x = 1 deklaruje zmienną x w bieżącym zakresie (aka execution context). Jeśli deklaracja pojawia się w funkcji - deklarowana jest zmienna lokalna; jeśli jest w zasięgu globalnym - deklarowana jest zmienna globalna.

x = 1, z drugiej strony jest to jedynie cesja nieruchomości. Najpierw próbuje rozwiązać x przeciwko łańcuchowi zakresu. Jeśli znajdzie go w dowolnym miejscu w tym łańcuchu zakresu, wykonuje przypisanie; jeśli nie znajdzie x, dopiero wtedy tworzy Właściwość x na obiekcie globalnym (który jest obiektem najwyższego poziomu w łańcuchu zakresu).

Zauważ, że nie deklaruje zmiennej globalnej, tylko tworzy właściwość globalną.

Różnica między nimi jest subtelna i może być myląca, chyba że zrozumiesz, że deklaracje zmiennych również tworzą właściwości (tylko na obiekcie zmiennej) i że każda właściwość w Javascript (dobrze, ECMAScript) ma pewne flagi opisujące ich właściwości - ReadOnly, DontEnum i DontDelete.

Ponieważ deklaracja zmiennej tworzy właściwość ze znacznikiem DontDelete, różnica między var x = 1 i x = 1 (gdy jest wykonywana w zasięgu globalnym) jest taka, że pierwsza - deklaracja zmiennej - tworzy właściwość dontdelete ' able, a druga nie. w konsekwencji, właściwość utworzona przez to niejawne przypisanie może zostać usunięta z obiektu globalnego, a pierwsza - ta utworzona przez deklarację zmiennej - nie może zostać usunięta. usunięte.

Ale to oczywiście tylko teoria, a w praktyce jest jeszcze więcej różnic między tymi dwoma , z powodu różnych błędów w implementacjach (takich jak te z IE).

Mam nadzieję, że wszystko ma sens:)


[Aktualizacja 2010/12/16]

W ES5 (ECMAScript 5; ostatnio ustandaryzowane, piąte wydanie języka) istnieje tak zwany "tryb ścisły"-tryb języka opt - in, który nieznacznie zmienia zachowanie nierejestrowanych zadań. W tryb ścisły, przypisanie do nierejestrowanego identyfikatora to ReferenceError. Powodem tego było wychwytywanie przypadkowych przydziałów, uniemożliwiających tworzenie niepożądanych globalnych właściwości. Niektóre z nowszych przeglądarek już rozpoczęły obsługę trybu ścisłego. Zobacz, na przykład, moja tabela compat .

 702
Author: kangax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 12:37:57

Stwierdzenie, że to różnica między " lokalnym iglobalnym " nie jest do końca dokładne.

Może lepiej pomyśleć o tym jako o różnicy między "local i nearest". Najbliższy z pewnością może być globalny, ale nie zawsze tak będzie.

/* 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;
    }
}
 130
Author: Jonathan Lonowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-24 09:50:34

Gdy Javascript jest wykonywany w przeglądarce, cały Twój kod jest otoczony instrukcją with, w ten sposób:

with (window) {
    //Your code
}

Więcej informacji na with - MDN

Ponieważ var deklaruje zmienną w bieżącym zakresie , nie ma różnicy między deklarowaniem var wewnątrz okna i nie deklarując go w ogóle.

Różnica pojawia się, gdy nie jesteś bezpośrednio wewnątrz okna, np. wewnątrz funkcji lub wewnątrz bloku.

Using var lets ukrywasz zewnętrzne zmienne o tej samej nazwie. W ten sposób można symulować zmienną "prywatną", ale to już inny temat.

Zasadą jest zawsze używać var, ponieważ w przeciwnym razie ryzykujesz wprowadzenie subtelnych błędów.

Edytuj: Po krytyce, którą otrzymałem, chciałbym podkreślić, co następuje:

  • var deklaruje zmienną w bieżącym zakresie
  • zasięg globalny to window
  • nie używać var w sposób dorozumiany deklaruje var w globalnym zasięgu (okno)
  • deklarowanie zmiennej w globalnym zasięgu (oknie) za pomocą var jest tym samym, co pomijanie jej.
  • deklarowanie zmiennej w zakresach innych niż window za pomocą var to nie to samo co deklarowanie zmiennej bez var
  • zawsze deklaruj var wyraźnie, ponieważ jest to dobra praktyka
 76
Author: kentaromiura,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-03 02:49:19

Powinieneś zawsze używać słowa kluczowego var do deklarowania zmiennych. Dlaczego? Dobra praktyka kodowania sama w sobie powinna być wystarczającym powodem, ale deklarowanie zmiennej bez słowa kluczowego var oznacza, że jest ona zadeklarowana w global (taka zmienna nazywana jest "implikowaną" globalną). Douglas Crockford zaleca nigdy nie używać domniemanych globals , a zgodnie z Apple JavaScript Coding Guidelines :

Dowolna zmienna utworzona bez var słowo kluczowe jest tworzone w zasięgu globalnym i nie jest śmieci zbierane, gdy funkcja zwraca (ponieważ nie go out of scope), prezentując szansa na wyciek pamięci.

Tak więc, w skrócie, zawsze deklaruj zmienne za pomocą słowa kluczowego var.

 37
Author: Steve Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-24 09:52:16

Oto całkiem dobry przykład, jak możesz zostać złapany z nie deklarowania zmiennych lokalnych za pomocą var:

<script>
one();

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

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

(i jest resetowana przy każdej iteracji pętli, ponieważ nie jest deklarowana lokalnie w pętli for, ale globalnie), co ostatecznie skutkuje nieskończoną pętlą

 27
Author: Chris S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-10 08:01:44

Powiedziałbym, że lepiej użyć var w większości sytuacji.

Zmienne lokalne są zawsze szybsze niż zmienne w zasięgu globalnym.

Jeśli nie stosować var aby zadeklarować zmienną, zmienna będzie miała zasięg globalny.

Aby uzyskać więcej informacji, możesz wyszukać "scope Chain JavaScript" w Google.

 12
Author: Billy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-04 17:31:20

Kolejna różnica e. g

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

While

a = a || [] ; // a is undefined error.
 8
Author: Pranay Warke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-09 22:11:28

Bez var - zmienna globalna.

Zaleca się, aby zawsze używać instrukcji var, ponieważ INIT zmienna globalna w kontekście lokalnym - jest zła. Ale jeśli potrzebujesz tej brudnej sztuczki, powinieneś napisać komentarz na początku strony:

/* global: varname1, varname2... */
 8
Author: Anatoliy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-04 17:21:38

Użycie var jest zawsze dobrym pomysłem, aby zapobiec zaśmiecaniu globalnego zakresu zmiennych i kolidowaniu zmiennych ze sobą, powodując niechciane nadpisanie.

 7
Author: mc10,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-04 23:14:43

Nie używaj var!

var był to pre-ES6 sposób deklarowania zmiennej. Jesteśmy teraz w przyszłości i powinniście być kodowani jako tacy.

Użyj const i let

const należy stosować w 95% przypadków. Powoduje to, że odniesienie do zmiennej nie może się zmienić, więc właściwości węzła array, object i Dom mogą się zmienić i prawdopodobnie powinny być const.

let powinien być stosowany dla każdej zmiennej oczekującej ponownego przypisania. Obejmuje to pętlę for. Jeśli jeśli piszesz varName = poza inicjalizacją, użyj let.

Oba mają zakres blokowy, zgodnie z oczekiwaniami w większości innych języków.

 5
Author: Gibolt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-15 20:12:47

Oto przykładowy kod, który napisałem dla ciebie, aby zrozumieć tę koncepcję:

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
 2
Author: newday,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-06 14:52:31

Wewnątrz kodu jeśli używasz zmiennej bez użycia var, wtedy automatycznie var nazwa Var jest umieszczana w globalnym zakresie np:

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 */
}
 1
Author: Akash Arora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-13 23:00:22

Bez użycia "var" zmienne mogą definiować tylko wtedy, gdy ustawia się wartość. W przykładzie:

my_var;

Nie może działać w globalnym zakresie lub jakimkolwiek innym zakresie . Powinno być z wartością taką jak:

my_var = "value";

Z drugiej strony można zdefiniować vaiable like;

var my_var;

Jego wartość to undefined (jego wartość nie jest null i nie jest równa null co ciekawe.).

 0
Author: umut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-27 04:28:08

Jako ktoś, kto próbuje się tego nauczyć, tak to widzę. Powyższe przykłady były może nieco zbyt skomplikowane dla początkujących.

Jeśli uruchomisz ten kod:

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);

Wyjście będzie odczytywane jako: false, false, true, true

Ponieważ widzi zmienne w funkcji jako oddzielone od tych spoza niej, stąd termin zmienna lokalna i to dlatego, że użyliśmy var w przypisaniu. Jeśli usuniesz var w funkcji, to teraz będzie to brzmiało jak to:

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);

Wyjście to false, false, false, false

Dzieje się tak dlatego, że zamiast tworzyć nową zmienną w lokalnym zakresie lub funkcji, po prostu używa zmiennych globalnych i przypisuje je do false.

 0
Author: Danrex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-01 03:14:08

Widzę, że ludzie są zdezorientowani, gdy deklarują zmienne Z lub bez var i wewnątrz lub na zewnątrz funkcji. Oto głęboki przykład, który poprowadzi Cię przez te kroki:

Zobacz poniższy skrypt w akcji tutaj w 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);

Wniosek

  1. bez względu na zadeklarowane z var lub bez var (jak a, b), jeśli otrzymają swoją wartość poza funkcją, zachowają swoją wartość, a także wszelkie inne wartości, które zostaną dodane wewnątrz różnych funkcji poprzez skrypt są zachowane.
  2. jeśli zmienna jest zadeklarowana bez var wewnątrz funkcji (jak c), będzie działać jak poprzednia reguła, zachowa swoją wartość we wszystkich funkcjach od teraz. Albo pierwsza wartość została otrzymana w funkcji testVar1 (), to nadal zachowuje wartość i otrzymuje dodatkową wartość w funkcji testVar2 ()
  3. jeśli zmienna jest zadeklarowana z var tylko wewnątrz funkcji (jak d w testVar1 lub testVar2) będzie to undefined ilekroć Funkcja się kończy. Będzie więc zmienną tymczasową w funkcji.
 0
Author: Tarik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-20 06:50:32

Powinieneś użyć słowa kluczowego var, chyba że chcesz mieć zmienną dołączoną do obiektu window w przeglądarce. Oto link, który wyjaśnia zakres i różnicę między zakresem glocal i zakresem lokalnym ze słowem kluczowym and wittout var.

Gdy zmienne są definiowane bez użycia słowa kluczowego var, to wygląda to jak prosta operacja "przypisanie".

Gdy wartość jest przypisana do zmiennej w javascript, interpreter najpierw próbuje znaleźć " deklarację zmiennej" w tym samym kontekście/zakresie, co przyporządkowanie. Kiedy interpreter wykonuje dummyVariable = 20, wyszukuje deklarację dummyVariable na początku funkcji. (Ponieważ wszystkie deklaracje zmiennych są przenoszone na początek kontekstu przez interpreter javascript i nazywa się to podnoszeniem)

Możesz również spojrzeć na podnoszenie w javascript

 0
Author: Simran kaur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-12 04:22:34

@Chris s dał ładny przykład pokazujący praktyczną różnicę (i niebezpieczeństwo) między var i nie var. Oto kolejny, ten uważam za szczególnie niebezpieczny, ponieważ różnica jest widoczna tylko w środowisku asynchronicznym, więc może łatwo wymknąć się podczas testów.

Jak można się spodziewać następujących wyjść snippet ["text"]:

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

console.log(var_fun())

Tak samo jak Poniższy fragment (zwróć uwagę na brakujące let przed array):

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

console.log(var_fun())

Asynchronicznie wykonywanie manipulacji danymi daje ten sam wynik z jednym executorem:

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

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

Ale zachowuje się inaczej z wieloma:

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)})
})

Użycie let jednak:

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)})
})
 0
Author: thisismydesign,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-29 00:46:27