Care este scopul cuvântului cheie var și când ar trebui să-l folosesc (sau să-l omit)?

NOTĂ: această întrebare a fost pusă din punctul de vedere al ECMAScript versiunea 3 sau 5. Răspunsurile ar putea deveni depășite odată cu introducerea de noi funcții în lansarea ECMAScript 6.

Care este exact funcția cuvântului cheie var în JavaScript și care este diferența dintre acestea

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

și

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

?

Când ați folosi oricare dintre ele și de ce/ce face?


person Alex    schedule 24.09.2009    source sursă
comment
Când înlănțuiți declarațiile var, punerea unei linii noi după virgulă afectează comportamentul? var x=1, y=2, [întoarcere]z=3;   -  person Alfabravo    schedule 20.11.2011
comment
Eșecul de a utiliza var vă lasă expus în cazul în care numele variabilei pe care l-ați ales se întâmplă să fie o variabilă globală definită anterior. Vedeți călătoria mea de durere aici: stackoverflow.com/questions/16704014/   -  person Scott C Wilson    schedule 23.05.2013
comment
Postarea pe blog a lui @Ray Toal pe meloncard (cu siguranță merită citită) s-a mutat la blog.safeshepherd.com/23/how-one-missing-var-ruined-our-launch   -  person Hephaestus    schedule 02.03.2014
comment
Nu mi-am imaginat niciodată că o poezie ar putea să-mi inspire considerație pentru o problemă programatică   -  person Félix Adriyel Gagnon-Grenier    schedule 15.03.2015
comment
Folosiți const și let în schimb! var nu este JS modern   -  person Gibolt    schedule 15.08.2017
comment
@Gibolt, dar uită-te la data întrebării, este o chemare oarecum nedreaptă a unei întrebări din 2009 pentru a spune asta. Chiar dacă, este încă valabil ca în data actuală pentru menținere, există o grămadă de cod JS care nu este modern.   -  person Andre Figueiredo    schedule 16.03.2018
comment
Speranța este că cineva care citește comentariul meu și care este nou în JS (probabil dacă caută acest lucru) va învăța devreme. Doar pentru că există cod non-modern, nu înseamnă că ar trebui să continuăm să-l împingem ca răspuns corect   -  person Gibolt    schedule 16.03.2018
comment
Rețineți că, în JavaScript modern, ar trebui să utilizați de obicei let în loc de var (datorită diferențelor în modul în care se comportă let și var).   -  person Quentin    schedule 19.12.2019


Răspunsuri (19)


Dacă sunteți în domeniul global, atunci nu este prea mare diferență. Citiți răspunsul Kangax pentru explicații

Dacă vă aflați într-o funcție, atunci var va crea o variabilă locală, „no var” va căuta în lanțul domeniului până când găsește variabila sau atinge domeniul global ( moment în care o va crea ):

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

Dacă nu faci o misiune, atunci trebuie să folosești var:

var x; // Declare x
person Greg    schedule 24.09.2009
comment
Nu este chiar mare diferență == Nicio diferență? - person Alex; 24.09.2009
comment
Ei bine, de fapt da, există o diferență :) Dacă acea diferență este importantă este o altă întrebare. Vedeți răspunsul meu mai jos: stackoverflow.com/questions/1470488/ - person kangax; 25.09.2009
comment
Cred că acesta poate fi punctul lui Alex, motiv pentru care a scris-o folosind este egal cu operatorul! - person James Bedford; 13.09.2012
comment
Este ca și cum te-ai împușca cu un pistol cu ​​șină... Uită să pui un „var” înaintea variabilei tale și ajungi să modifici o variabilă undeva în lanțul lunetei... Încearcă să convingi un Java/C/Python /etc. dezvoltator că JavaScript merită. Ha! Capcanele C/C++ arată bine prin contrast. Imaginați-vă că trebuie să depanați JavaScript... Și unii oameni fac asta, desigur. Și există atât de mult cod (și nu cod simplu, ține cont) scris în JavaScript... - person Albus Dumbledore; 24.02.2013
comment
Dacă vă aflați în domeniul global, atunci nu există nicio diferență. ›› există o diferență care este explicată în răspunsul de mai jos - person Max Koretskyi; 13.09.2013
comment
@Alex 0 == fals, deci da nu prea multă diferență == Nicio diferență, totuși nu prea mare diferență!== Nicio diferență - person Math chiller; 14.11.2013
comment
Dacă în modul strict, chiar și în domeniul global, veți avea nevoie de var pentru a-l declara. - person Juan Mendes; 15.11.2013
comment
dacă „utilizați strict”;, atunci ar trebui să utilizați var. - person WarFox; 24.03.2014
comment
acest lucru este important dacă doriți să păstrați API-ul public / membrii privați ai modelului de modul. înțelegerea faptului că var va plasa obiecte în domeniul local al modulului este esențială. Multumesc pentru explicatie. De asemenea, de remarcat dacă sunt corect, funcția x() este echivalentă cu var x = function() și diferă de x = function() în ceea ce privește domeniul de aplicare. - person ferr; 10.09.2014
comment
Mulțumesc foarte mult. M-am luptat cu asta de secole, apoi am citit această linie: „Dacă sunteți într-o funcție, atunci var va crea o variabilă locală, niciun var nu va căuta în lanțul domeniului până când va găsi variabila sau atinge domeniul global ( moment în care îl va crea)' - explicație perfectă, mulțumesc. - person developerbmw; 04.02.2015
comment
ce vrei să spui prin crearea unei închideri? - person NuWin; 31.07.2016
comment
Aceasta este o mare diferență: variabilele declarate cu var există înainte de începerea execuției, cele care nu există nu există până când instrucțiunea care le creează este executată. De asemenea, cele declarate cu var nu sunt șterse, în timp ce cele care nu sunt sunt proprietăți de ștergere ale obiectului global. De asemenea, funcția anonimă creează închideri pentru toate variabilele exterioare, nu doar pentru cele globale (adică are o închidere pentru foo, bar și moo. - person RobG; 07.11.2017
comment
Consultați și stackoverflow.com/questions/38270470/ pentru un exemplu interesant de diferență mai subtilă între cele două declarații. - person Mihai Târnovan; 28.09.2018
comment
Expresia ... moment în care o va crea are o formulare foarte ambiguă - întrebarea mea este încă nerezolvată. Este acel punct legat de fluxul logic? (de exemplu, nu se găsește nicăieri, așadar creat.. local) Sau punctul are legătură cu sfera, la care variabilă este creată? (de exemplu, variabilă căutată până la sfera globală, nu a fost găsită nici măcar acolo, deci creată acolo). Ați putea reformula puțin, vă rog? - person xakepp35; 21.10.2018
comment
Pentru codul C++, ieșirea int i=1; { cout<<i; int i=2; cout<<i; } cout<<i; ar fi: 121. Este un comportament var- sau var mai puțin? - person xakepp35; 21.10.2018

Există o diferență.

var x = 1 declară variabila x în domeniul curent (alias contextul de execuție). Dacă declarația apare într-o funcție - este declarată o variabilă locală; dacă este în domeniul global - este declarată o variabilă globală.

x = 1, pe de altă parte, este doar o atribuire de proprietate. Mai întâi încearcă să rezolve x împotriva lanțului scope. Dacă îl găsește oriunde în lanțul respectiv, efectuează atribuirea; dacă nu găsește x, numai atunci creează proprietatea x pe un obiect global (care este un obiect de nivel superior într-un lanț de domeniu).

Acum, observați că nu declară o variabilă globală, ci creează o proprietate globală.

Diferența dintre cele două este subtilă și poate fi confuză, dacă nu înțelegeți că declarațiile de variabile creează și proprietăți (numai pe un obiect variabil) și că fiecare proprietate din Javascript (ei bine, ECMAScript) are anumite steaguri care descriu proprietățile lor - ReadOnly, DontEnum și DontDelete.

Deoarece declarația variabilei creează o proprietate cu indicatorul DontDelete, diferența dintre var x = 1 și x = 1 (când este executată în sfera globală) este că prima - declarația variabilei - creează proprietatea DontDelete, iar cea din urmă nu. În consecință, proprietatea creată prin această atribuire implicită poate fi apoi ștearsă din obiectul global, iar cea dintâi - cea creată prin declararea variabilei - nu poate fi ștearsă.

Dar aceasta este doar teorie, desigur, iar în practică există și mai multe diferențe între cele două, din cauza diferitelor erori în implementări (cum ar fi cele de la IE).

Sper ca totul are sens :)


[Actualizare 2010/12/16]

În ES5 (ECMAScript 5; standardizat recent, ediția a 5-a a limbajului) există așa-numitul „mod strict” - un mod de limbă opt-in, care modifică ușor comportamentul sarcinilor nedeclarate. În modul strict, atribuirea unui identificator nedeclarat este o ReferenceError. Motivul pentru aceasta a fost de a surprinde sarcini accidentale, prevenind crearea de proprietăți globale nedorite. Unele dintre browserele mai noi au început deja să accepte modul strict. Vedeți, de exemplu, my compat table.

person kangax    schedule 24.09.2009
comment
Dacă îmi amintesc corect, cred că am găsit odată o modalitate de a putea delete o variabilă declarată var cu un hack eval. Dacă îmi amintesc trucul exact, voi posta aici. - person Tower; 30.06.2011
comment
@Mageek S-ar putea să ia despre variabilele declarate de eval care pot fi șterse. Am scris o post de blog despre aceasta o dată. - person kangax; 20.06.2012
comment
Puțin în afara subiectului, dar menționându-l aici pentru referință. let este foarte asemănător cu var și este acceptat în Mozilla. Principala diferență este că domeniul de aplicare al unei variabile var este întreaga funcție de încadrare, unde as let este restricționat la blocul său - person mac; 01.10.2012
comment
@kangax ce se întâmplă dacă ultimele două rânduri din exemplele lui Alex ar fi amestecate: var someObject = {} și someObject.someProperty = 5? Ar deveni someProperty global, în timp ce obiectul pentru care este o proprietate rămâne local? - person snapfractalpop; 28.11.2012
comment
Numele specificației pentru ceea ce @kangax numește indicatorul DontDelete este configurabil (= false), puteți citi despre acest lucru în ceea ce privește Object.defineProperty și Object.getOwnPropertyDescriptor - person Paul S.; 08.01.2014
comment
în unele versiuni IE există o eroare care vă permite să ștergeți o declarație de variabilă în domeniul global - person Shiala; 19.12.2014
comment
@Shiala Îmi amintesc așa ceva. Cred că numai cu variabile care umbră (au același nume ca) global built-in-uri, dar nu sunt sigur. - person kangax; 19.12.2014
comment
Nu sunt în apropierea unui computer acum, dar dacă memoria îmi servește bine, am încercat cu var x = 0; și IE nu m-a împiedicat să-l șterg. - person Shiala; 19.12.2014
comment
Ar fi bine să vedem o actualizare suplimentară a acestui răspuns care detaliază modul în care let ia în considerare întrebarea OP. - person Snekse; 24.09.2015
comment
@Snekse let nu afectează x = 1 parte a răspunsului, așa că singura diferență este în var x = 1 față de let x = 1. Acest lucru a fost documentat de multe ori în multe locuri, dar cele două diferențe principale sunt că let este blocat și creează TDZ (zonă moartă temporală), ceea ce înseamnă că nu îl puteți utiliza sau nici măcar nu îl puteți face referire înainte de declarare. - person kangax; 29.09.2015
comment
@kangax înțeleg asta. Spun doar că, dacă cineva care nu a auzit niciodată de let dă peste acest răspuns, ar fi bine să menționeze doar let și să se conecteze la o altă sursă de informații, astfel încât să poată citi. - person Snekse; 29.09.2015

A spune că este diferența dintre „local și global” nu este complet corect.

Ar fi mai bine să ne gândim la aceasta ca fiind diferența dintre „local și cel mai apropiat”. Cel mai apropiat poate fi cu siguranță global, dar nu va fi întotdeauna cazul.

/* 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
Cel mai apropiat domeniu de aplicare nu este outer unde definiți var global = false;? - person Snekse; 19.04.2013
comment
@Snekse: „cel mai apropiat” nu se aplică atunci când este declarat ‹code›var global = false;‹/code›. În acea declarație, „global” este plasat în domeniul de aplicare al lui outer() deoarece „var” este folosit în declarație. Deoarece „var” nu este folosit în inner(), aceasta va schimba valoarea la nivelul următor, care este outer(). - person Mitch; 18.09.2015
comment
Mă întreb dacă comentariul s-ar schimba dacă ai schimba acea linie la var global = local;, caz în care sfera apropiată a localului ar fi sfera externă locală care este definită în mod activ. Deși devine ciudat dacă ați schimba aceeași linie la var global = global, caz în care cel mai apropiat domeniu atunci când căutați valoarea lui global ar fi mai sus la nivelul ferestrei globale. - person Snekse; 24.09.2015

Când Javascript este executat într-un browser, tot codul dvs. este înconjurat de o instrucțiune with, astfel:

with (window) {
    //Your code
}

Mai multe informații despre with - MDN

Deoarece var declară o variabilă în domeniul curent , nu există nicio diferență între a declara var în interiorul ferestrei și a nu o declara deloc.

Diferența vine atunci când nu ești direct în interiorul ferestrei, de ex. în interiorul unei funcţii sau în interiorul unui bloc.

Utilizarea var vă permite să ascundeți variabile externe care au același nume. În acest fel puteți simula o variabilă „privată”, dar acesta este un alt subiect.

O regulă generală este să folosiți întotdeauna var, pentru că altfel riscați să introduceți erori subtile.

EDIT: După criticile pe care le-am primit, aș dori să subliniez următoarele:

  • var declară o variabilă în domeniul curent
  • Domeniul de aplicare global este window
  • Neutilizarea var declară implicit var în domeniul global (fereastră)
  • Declararea unei variabile în domeniul global (fereastră) folosind var este același lucru cu omiterea acesteia.
  • Declararea unei variabile în domenii diferite de fereastră folosind var nu este același lucru cu declararea unei variabile fără var
  • Declarați întotdeauna var în mod explicit, deoarece este o practică bună
person kentaromiura    schedule 24.09.2009
comment
Nu te-am votat negativ, dar scope este probabil un cuvânt mai bun decât fereastră. Toată explicația ta este puțin obtuză. - person Robert Harvey; 25.09.2009
comment
Pur și simplu numesc lucrurile cu numele lui, vrei să-i denumești scope global, este în regulă, dar partea clientului, prin convenție, este obiectul fereastră, acesta este ultimul element al lanțului scope, de aceea poți apela fiecare funcție și fiecare obiect din fereastră fără fereastră de scriere. - person kentaromiura; 25.09.2009
comment
+1, aceasta este o explicație foarte bună - nu am mai auzit problema var/no var încadrată (fără joc de cuvinte) ca aceasta. - person doug; 10.04.2012
comment
Majoritatea acestui răspuns este depreciat cu let în ES6. - person Evan Carroll; 21.01.2014
comment
@EvanCarroll Acest răspuns este, de asemenea, incorect din punct de vedere tehnic, deoarece omiterea var nu declară nicio variabilă, în schimb creează o proprietate care poate fi ștearsă pe obiectul global, în plus, cu ES5, folosește modul strict, cea mai mare parte a răspunsului nu este în mod evident corectă, de asemenea, nici măcar nu a fost luat în considerare în acest răspuns, deoarece la momentul întrebării nu exista nicio referire la versiunea javascript (adăugata ieri) care implică faptul că standardul de referință (la momentul respectiv) era ECMA 262 ediția a treia. - person kentaromiura; 22.01.2014
comment
Declarația tot codul tău este înconjurat de o declarație with este greșită. Dacă acest lucru ar fi adevărat, numele variabilelor ar fi rezolvate pe obiectul fereastră înainte de domeniul local. - person RobG; 07.11.2017

Utilizați întotdeauna cuvântul cheie var pentru a declara variabile. De ce? Buna practică de codificare ar trebui să fie un motiv suficient în sine, dar omiterea acesteia înseamnă că este declarată în domeniul global (o variabilă ca aceasta se numește globală „implicite”). Douglas Crockford recomandă să nu folosiți niciodată valori globale implicite și în conformitate cu Orientări de codare JavaScript Apple:

Orice variabilă creată fără cuvântul cheie var este creată la nivel global și nu este colectată de gunoi atunci când funcția revine (pentru că nu iese din domeniul de aplicare), prezentând oportunitatea unei scurgeri de memorie.

person Steve Harrison    schedule 24.09.2009
comment
O bună practică de codificare nu ar trebui să fie niciodată un motiv suficient în sine. Se pare că unii tipi de pe internet au spus că așa ar trebui să arate codul meu. Acest lucru este chiar mai puțin valid decât a spus profesorul meu, cu excepția cazului în care cineva înțelege cel puțin vag motivul din spatele regulii. - person cHao; 24.05.2013
comment
@cHao Cred că good coding practice este întotdeauna un motiv suficient dacă este o practică recomandată, ceea ce este și de mai mulți autori Javascript. - person Chris S; 03.01.2014
comment
@ChrisS: Nu, o bună practică de codificare nu este un motiv în sine. Motivul pentru care este considerată o bună practică este ceea ce contează. Dacă autorii respectivi nu vă spun de ce îl recomandă, recomandarea lor nu ar trebui să aibă nicio importanță. Dacă nu sunteți de acord cu motivele, atunci sunteți liber să îl considerați un sfat prost. Și dacă îl urmărești fără să întrebi vreodată de ce, așa începe cultul cargo. - person cHao; 03.01.2014

Iată un exemplu destul de bun despre cum poți fi prins de a nu declara variabile locale cu var:

<script>
one();

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

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

(i este resetat la fiecare iterație a buclei, deoarece nu este declarat local în bucla for, ci global) rezultând în cele din urmă în buclă infinită

person Chris S    schedule 24.09.2009
comment
Da! Îmi pot imagina toate erorile care ar putea fi cauzate de acea greșeală de scriere. - person BonsaiOak; 13.10.2014
comment
Sunt curios, de ce îi dai i ca argument pentru doi()? (în interiorul buclei for) este redundant? - person kalin; 03.10.2016
comment
Argumentul este ignorat în funcția two() încapsulată în funcția one(), deoarece funcția two() a fost definită fără un parametru. Ai dreptate, nu este necesar, deoarece nu joacă un rol. - person KK.; 24.02.2017
comment
Eroare sau caracteristică? - person TheMaster; 25.08.2019

Aș spune că este mai bine să folosiți var în majoritatea situațiilor.

Variabilele locale sunt întotdeauna mai rapide decât variabilele din domeniul global.

Dacă nu utilizați var pentru a declara o variabilă, variabila va fi în domeniul global.

Pentru mai multe informații, puteți căuta „scope chain JavaScript” în Google.

person Billy    schedule 24.09.2009
comment
Dacă declarați o variabilă folosind cuvântul cheie var, aceasta va fi creată în timpul execuției, așa că nu ar trebui să fie mai lent? Pentru că celălalt este creat la momentul analizat. - person Barış Velioğlu; 14.08.2012
comment
@RyuKaplan - hei, este adevărat? Am încercat să caut pe google și nu am reușit să obțin informații despre acest subiect! Aveți o autoritate sursă pentru această afirmație? Mersi - person mike rodent; 12.04.2013
comment
@RyuKaplan Analiza/compilarea este diferită de rularea efectivă a codului. - person gcampbell; 08.07.2016

Nu folosi var!

var a fost modalitatea pre-ES6 de a declara o variabilă. Suntem acum în viitor și ar trebui să codificați ca atare.

Folosiți const și let

const ar trebui utilizat pentru 95% din cazuri. Face ca referința variabilei să nu se poată modifica, astfel încât proprietățile matricei, obiectului și nodului DOM se pot schimba și ar trebui probabil să fie const.

let ar trebui să fie utilizat pentru orice variabilă care se așteaptă să fie reatribuită. Aceasta include într-o buclă for. Dacă scrieți vreodată varName = dincolo de inițializare, utilizați let.

Ambele au domeniul de aplicare la nivel de bloc, așa cum era de așteptat în majoritatea celorlalte limbi.

person Gibolt    schedule 15.08.2017
comment
Înlocuiește tot ce ai „var” cu „const” (înlocuiește tot). Veți observa rapid unde sunt variabilele reatribuite. Dacă aveți prea multe dintre ele, probabil că codificați anti-pattern: majoritatea variabilelor reatribuibile pot fi încorporate în închideri sau ca proprietăți-obiect. Dacă aveți câteva: folosiți „las” pentru ele. În cele din urmă, dacă unele variabile nu au fost eliminate deloc cu „var”, ele vor rămâne nedeclarate și sunt încă prezente în spațiul global, atenție. Despre @Gibolt comentează „într-o buclă for”, de asemenea, se recomandă evitarea unor astfel de bucle în 95% din cazuri ;-): metodele de matrice sunt grozave. - person allez l'OM; 21.10.2018
comment
Spunând că const ar trebui să fie folosit în 95% din cazuri, se pare că ne îndepărtăm de la bună practică și trecem la dogmă. - person Agamemnus; 28.12.2018

alta diferenta de ex

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

in timp ce

a = a || [] ; // a is undefined error.
person Pranay Warke    schedule 09.08.2013
comment
Ați putea explica de ce funcționează în cazul variabilei definite cu „var” și variabilei nedefinite cu var? Este variabila creată înainte de evaluarea părții drepte a atribuirii în cazul var? - person matt; 05.12.2013
comment
@Lucek, deoarece var a este ridicat în partea de sus a domeniului de aplicare și setat la null, care declară, dar nu inițializează variabila, atunci în alocare aveți o referință la o variabilă nulă nedefinită care se evaluează ca fals și setați atribuirea la []. În cel din urmă, aveți o atribuire la proprietatea a a proprietății a. Puteți atribui unei proprietăți care nu există -- creând-o la atribuire, dar nu puteți citi dintr-o proprietate care nu există fără a primi un ReferenceError. - person Evan Carroll; 20.01.2014
comment
@EvanCarroll: este ridicat în partea de sus a domeniului de aplicare și este setat la nedefinit în loc de nul. - person Mithun Satheesh; 25.09.2014

Folosirea var este întotdeauna o idee bună pentru a preveni ca variabilele să aglomereze domeniul de aplicare global și variabilele să intre în conflict între ele, provocând suprascriere nedorită.

person kevinji    schedule 04.04.2011

Fără var - variabilă globală.

Se recomandă să folosiți ÎNTOTDEAUNA instrucțiunea var, deoarece variabila globală init în context local - este rău. Dar, dacă aveți nevoie de acest truc murdar, ar trebui să scrieți un comentariu la începutul paginii:

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

Acesta este un exemplu de cod pe care l-am scris pentru a înțelege acest concept:

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
Funcția nu este deloc anonimă. De fapt, se numește cât se poate de vizibil. - person Ingo Bürk; 23.01.2014
comment
Vă mulțumim că v-ați editat răspunsul, ca răspuns la comentariul lui Ingo Bürk, pentru ca funcția anonimă să fie de fapt anonimă. - person Dave Burton; 09.09.2016

@Chris S a dat un exemplu frumos care arată diferența practică (și pericolul) dintre var și nu var. Iată un altul, acesta îl găsesc deosebit de periculos, deoarece diferența este vizibilă doar într-un mediu asincron, așa că poate scăpa cu ușurință în timpul testării.

După cum v-ați aștepta la următoarele ieșiri de fragment ["text"]:

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

console.log(var_fun())

La fel și următorul fragment (rețineți let lipsă înainte de array):

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

console.log(var_fun())

Executarea asincronă a manipulării datelor produce în continuare același rezultat cu un singur executor:

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

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

Dar se comportă diferit cu mai multe:

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

Folosind let totuși:

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
Mulțumesc pentru exemplu @thisismydesign! În ceea ce privește ultimele două exemple, de ce penultimul exemplu înregistrează o matrice de 3 elemente cu text scris de trei ori, în timp ce exemplul final înregistrează doar textul o dată pe element din matrice? (Înțeleg că ultimul declară matrice ca variabilă și, prin urmare, este în domeniul local, în timp ce penultimul exemplu omite acest lucru, făcând matricea o parte a domeniului global implicit.) Dar, de ce afectează acest lucru rezultatul? Este pentru că forEach i iterează peste funcție și toate variabilele globale? - person Brad Ahrens; 22.09.2019

Ca cineva care încearcă să învețe asta, așa văd eu. Exemplele de mai sus au fost poate puțin prea complicate pentru un începător.

Dacă rulați acest cod:

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

Rezultatul va fi: fals, false, true, true

Deoarece vede variabilele din funcție ca fiind separate de cele din afara acesteia, de unde termenul de variabilă locală și asta pentru că am folosit var în atribuire. Dacă eliminați var-ul din funcție, acum se citește astfel:

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

Rezultatul este fals, fals, false, false

Acest lucru se datorează faptului că, în loc să creeze o nouă variabilă în domeniul sau în funcție locală, pur și simplu folosește variabilele globale și le reatribuie la false.

person Danrex    schedule 01.10.2016

Văd că oamenii sunt confuzi când declară variabile cu sau fără var și în interiorul sau în afara funcției. Iată un exemplu profund care vă va ghida prin acești pași:

Vezi scriptul de mai jos în acțiune aici la 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);

Concluzie

  1. Indiferent dacă sunt declarate cu sau fără var (cum ar fi a, b), dacă își obțin valoarea în afara funcției, își vor păstra valoarea și, de asemenea, orice alte valori care sunt adăugate în interiorul diferitelor funcții prin intermediul scriptului sunt păstrate.
  2. Dacă variabila este declarată fără var în interiorul unei funcții (cum ar fi c), aceasta va acționa ca regula anterioară, își va păstra valoarea pentru toate funcțiile de acum înainte. Fie că a primit prima valoare în funcția testVar1(), încă păstrează valoarea și obține o valoare suplimentară în funcția testVar2()
  3. Dacă variabila este declarată cu var numai în interiorul unei funcții (cum ar fi d în testVar1 sau testVar2), aceasta va fi nedefinită ori de câte ori funcția se termină. Deci va fi o variabilă temporară într-o funcție.
person Tarik    schedule 20.11.2016
comment
Vă mulțumim pentru timpul acordat pentru a crea un exemplu pentru a demonstra acest subiect. Codul de mai sus lipsește partea de mai jos, așa că este posibil să doriți să editați răspunsul dvs.: a = 1;// Definit în afara funcției fără var var b = 1;// Definit în afara funcției cu var alert (Începând în afara tuturor funcțiilor. .. \n \n a, b definit dar c, d nu este încă definit: \n a: + a + \n b: + b + \n \n (Dacă încerc să arăt valoarea c sau d nedefinită, consolă. jurnalul ar arunca eroarea „Uncaught ReferenceError: c is not defined” și scriptul ar înceta să ruleze!)); - person Sankofa; 11.10.2018

În interiorul unui cod, dacă utilizați o variabilă fără a utiliza var, atunci ceea ce se întâmplă este că varul var_name este plasat automat în domeniul global, de exemplu:

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

Pe lângă problemele legate de domeniul de aplicare, unii oameni menționează și ascensiunea, dar nimeni nu a dat un exemplu. Iată unul pentru domeniul global:

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

Fără a utiliza „var” variabilele pot defini numai atunci când setați o valoare. De exemplu:

my_var;

nu poate funcționa în sfera globală sau orice alt domeniu. Ar trebui să aibă o valoare ca:

my_var = "value";

Pe de altă parte, puteți defini un like disponibil;

var my_var;

Valoarea sa este undefined (Valoarea sa nu este null și nu este egală cu null în mod interesant.).

person umut    schedule 27.04.2014
comment
my_var; este de fapt o expresie validă. - person lexicore; 27.11.2014
comment
Este o declarație validă dacă variabila este definită înainte. Altfel se aruncă o eroare... nu este definită. - person umut; 27.11.2014
comment
Este o declarație validă indiferent dacă o variabilă a fost definită înainte sau nu. :) O declarație validă poate arunca o eroare, nu face ca afirmația să fie invalidă. - person lexicore; 27.11.2014
comment
Sunt confuz în privința asta. Care este afirmația valabilă? Și poți să-mi dai un exemplu de declarație nevalidă? - person umut; 27.11.2014
comment
Va trebui să-mi cer scuze - prea multă gramatică ECMAScript în ultima vreme. my_var; este o instrucțiune de expresie validă. /my_var; ar fi o declarație nevalidă. Dar, așa cum am spus, aceasta este cazuistica gramaticală, îmi cer scuze, comentariul meu de fapt nu a fost potrivit. - person lexicore; 27.11.2014

Ar trebui să utilizați cuvântul cheie var, cu excepția cazului în care intenționați să atașați variabila obiectului fereastră în browser. Iată un link care explică domeniul de aplicare și diferența dintre delimitarea globală și delimitarea locală cu și fără cuvânt cheie var.

Când variabilele sunt definite fără utilizarea cuvântului cheie var, ceea ce arată este o operație simplă de „atribuire”.

Când valoarea este atribuită unei variabile în javascript, interpretul încearcă mai întâi să găsească „declarația variabilei” în același context/sfera de aplicare ca cel al atribuirii. Când interpretul execută dummyVariable = 20, caută declarația dummyVariable la începutul funcției. (Deoarece toate declarațiile de variabile sunt mutate la începutul contextului de către interpretul javascript și aceasta se numește ridicare)

De asemenea, vă recomandăm să vă uitați la hoisting în javascript

person S Khurana    schedule 12.12.2016