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


1543

UWAGA : Pytanie to zostało zadane z punktu widzenia ECMAScript w wersji 3 lub 5. Odpowiedzi mogą stać się nieaktualne po wprowadzeniu nowych funkcji w wydaniu ECMAScript 6.

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

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żyjesz jednego z nich i dlaczego / co to robi?


3
Czy umieszczanie nowego wiersza po przecinku podczas łączenia deklaracji var wpływa na zachowanie? var x = 1, y = 2, [return] z = 3;
Alfabravo,

4
Nieużywanie „var” również naraża cię na wypadek, gdyby wybrana nazwa zmiennej była wcześniej zdefiniowaną zmienną globalną. Zobacz moją żałobną podróż tutaj: stackoverflow.com/questions/16704014/...
Scott C Wilson

5
Post na blogu @Ray Toal na blogu meloncard (zdecydowanie wart przeczytania) został przeniesiony na blog.safeshepherd.com/23/how-one-missing-var-ruined-our-launch
Hefajstos

Nigdy nie wyobrażałem sobie, że wiersz może zainspirować mnie do rozważenia problemu programowego
Félix Gagnon-Grenier

1
@Gibolt, ale spójrz na datę pytania, to trochę niesprawiedliwe przywołanie pytania z 2009 roku, aby to powiedzieć. Mimo tego, że jest nadal aktualny, jak na bieżącą datę konserwacji, istnieje wiele nie „nowoczesnych JS” kodu.
Andre Figueiredo

Odpowiedzi:


1355

Jeśli jesteś w zasięgu globalnym, nie ma dużej różnicy. Przeczytaj odpowiedź Kangaxa, aby uzyskać wyjaśnienie

Jeśli jesteś w funkcji, wówczas varutworzy zmienną lokalną, „no var” przeszuka łańcuch zasięgu, dopóki nie znajdzie zmiennej lub nie dotrze do zasięgu globalnego (w którym momencie ją 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

31
Czy „nie ma tak naprawdę dużej różnicy” == „Bez różnicy”?
Alex

65
Właściwie tak, jest różnica :) Czy ta różnica jest ważna, to kolejne pytanie. Zobacz moją odpowiedź poniżej: stackoverflow.com/questions/1470488/…
kangax 25.09.09

4
Myślę, że to może być punkt Alexa, dlatego napisał go za pomocą operatora „równa się”!
James Bedford,

18
To tak, jakby strzelać sobie z karabinu ... Zapomnij o ustawieniu zmiennej przed zmienną i modyfikuj ją gdzieś w łańcuchu zasięgu ... Spróbuj przekonać Java / C / Python / etc. deweloper, że JavaScript jest wart. Ha! Natomiast pułapki C / C ++ wyglądają ładnie. Wyobraź sobie, że musisz debugować JavaScript ... I niektórzy ludzie to robią, oczywiście. I jest tak dużo kodu (i nie jest to prosty kod, pamiętajcie) napisanego w JavaScript ...
Albus Dumbledore

6
Jeśli jesteś w zasięgu globalnym, nie ma różnicy. >> istnieje różnica, która została wyjaśniona w odpowiedzi poniżej
Max Koretskyi

746

Jest różnica .

var x = 1 deklaruje zmienną x w bieżącym zakresie (inaczej kontekst wykonania). Jeśli deklaracja pojawia się w funkcji - deklarowana jest zmienna lokalna; jeśli ma zasięg globalny - deklarowana jest zmienna globalna.

x = 1z drugiej strony jest jedynie przeniesieniem własności. Najpierw próbuje rozwiązać problem xz łańcuchem zakresu. Jeśli znajdzie go gdziekolwiek w tym łańcuchu zasięgu, wykonuje przypisanie; jeśli nie znajdzie x, tylko wtedy tworzy xwłaściwość na obiekcie globalnym (który jest obiektem najwyższego poziomu w łańcuchu zasięgu).

Zauważ, że nie deklaruje zmiennej globalnej, lecz 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 zmiennym) i że każda właściwość w JavaScript (cóż, ECMAScript) ma pewne flagi opisujące ich właściwości - ReadOnly, DontEnum i DontDelete.

Ponieważ deklaracja zmiennej tworzy właściwość z flagą DontDelete, różnica między var x = 1i x = 1(gdy jest wykonywana w zasięgu globalnym) polega na tym, że pierwsza deklaracja - zmienna - tworzy właściwość DontDelete, a druga nie. W konsekwencji właściwość utworzona za pomocą tego niejawnego przypisania można następnie usunąć z obiektu globalnego, a poprzednia - ta utworzona za pomocą deklaracji zmiennej - nie może zostać usunięta.

Ale to oczywiście tylko teoria, aw praktyce istnieją między nimi jeszcze więcej różnic , z powodu różnych błędów we wdrożeniach (takich jak te z IE).

Mam nadzieję, że to wszystko ma sens :)


[Aktualizacja 2010/12/16]

W ES5 (ECMAScript 5; ostatnio znormalizowana, 5. edycja języka) znajduje się tak zwany „tryb ścisły” - opcjonalny tryb językowy, który nieznacznie zmienia zachowanie niezadeklarowanych zadań. W trybie ścisłym przypisanie do niezadeklarowanego identyfikatora to ReferenceError . Uzasadnieniem tego było złapanie przypadkowych zleceń, zapobiegając tworzeniu niepożądanych globalnych właściwości. Niektóre z nowszych przeglądarek już zaczęły obsługiwać tryb ścisły. Zobacz na przykład moją tabelę zgodności .


Jeśli dobrze pamiętam, myślę, że kiedyś znalazłem sposób, by móc deletezhackować zmienną deklarowaną przez zmienną eval. Jeśli pamiętam dokładną sztuczkę, opublikuję ją tutaj.
Tower

3
@Mageek Może zajmował się zmiennymi deklarowanymi przez eval, które można usunąć. Napisałem kiedyś na ten temat post na blogu .
kangax

1
Trochę nie na temat, ale wspominając o tym tutaj w celach informacyjnych. „let” jest bardzo podobne do „var” i jest obsługiwane w Mozilli. Główną różnicą jest to, że zakres zmiennej var jest całą obejmującą funkcją, gdzie jako „let” jest ograniczone do jego bloku
mac

@ kangax co, jeśli dwie ostatnie linie przykładów Alexa byłyby mieszane: var someObject = {}i someObject.someProperty = 5? Czy somePropertystałby się globalny, a obiekt, który jest własnością, pozostaje lokalny?
snapfractalpop

1
Nazwę specyfikacji dla tego, co @kangax nazywa flagą DontDelete, można konfigurować (= false) , możesz o tym przeczytać w odniesieniu do Object.definePropertyiObject.getOwnPropertyDescriptor
Paul S.

137

Mówienie, że różnica między „ lokalnym a globalnym ” nie jest do końca dokładne.

Lepiej byłoby myśleć o tym jak o różnicy między „ lokalnym a najbliższym ”. Najbliższy z pewnością może mieć charakter 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;
    }
}

3
Czy najbliższy zakres outernie jest zdefiniowany var global = false;?
Snekse

@Snekse: „najbliższy” nie ma zastosowania, gdy zadeklarowano <code> var global = false; </code>. W tej deklaracji „globalny” jest objęty zakresem external (), ponieważ w deklaracji użyto „var”. Ponieważ „var” nie jest używane w wewnętrznej (), zmieni wartość na następnym poziomie w górę, która jest zewnętrzna ().
Mitch,

Zastanawiam się, czy twój komentarz zmieniłby się, gdybyś zmienił tę linię, var global = local;w którym to przypadku bliski zasięg local byłby „lokalnym” zasięgiem zewnętrznym, który jest aktywnie definiowany. Choć dziwne staje się, gdybyś zmienił tę samą linię na, var global = globalw którym to przypadku najbliższy zakres podczas szukania wartości globalbyłby wyższy o poziom w zakresie globalnego okna.
Snekse

80

Kiedy JavaScript jest wykonywany w przeglądarce, cały kod jest otoczony instrukcją with, na przykład:

with (window) {
    //Your code
}

Więcej informacji na temat with- MDN

Ponieważ vardeklaruje zmienną w bieżącym zakresie , nie ma różnicy między zadeklarowaniem var w oknie a jej całkowitym zadeklarowaniem.

Różnica pojawia się, gdy nie jesteś bezpośrednio w oknie, np. W funkcji lub w bloku.

Użycie varpozwala ukryć zmienne zewnętrzne o tej samej nazwie. W ten sposób możesz symulować zmienną „prywatną”, ale to już inny temat.

Zasadą jest, aby zawsze używać var, ponieważ w przeciwnym razie istnieje ryzyko wprowadzenia subtelnych błędów.

EDYCJA: Po otrzymaniu krytyki chciałbym podkreślić następujące kwestie:

  • vardeklaruje zmienną w bieżącym zakresie
  • Globalny zasięg to window
  • Nieużywanie varniejawnie deklaruje varw zakresie globalnym (okno)
  • Zadeklarowanie zmiennej w zakresie globalnym (oknie) przy użyciu varjest tym samym, co pominięcie jej.
  • Zadeklarowanie zmiennej w zakresach innych niż użycie okna var nie jest tym samym, co zadeklarowanie zmiennej bezvar
  • Zawsze deklaruj varwyraźnie, ponieważ jest to dobra praktyka

1
Nie głosowałem cię, ale zakres jest prawdopodobnie lepszym słowem niż okno. Twoje całe wyjaśnienie jest trochę tępe.
Robert Harvey

4
Po prostu nazywam rzeczy swoją nazwą, chcesz nazwać to „zasięgiem globalnym”, jest w porządku, ale po stronie klienta, zgodnie z konwencją, jest obiektem okna, który jest ostatnim elementem łańcucha zasięgu, dlatego możesz wywoływać każdy funkcja i każdy obiekt w oknie bez zapisu „okno”.
kentaromiura

2
+1 to naprawdę miłe wytłumaczenie - wcześniej nie słyszałem takiego wydania var / no var (bez zamierzonej gry słów).
doug

Większość tej odpowiedzi jest przestarzała letw ES6.
Evan Carroll

3
@EvanCarroll Ta odpowiedź jest również technicznie niepoprawna, ponieważ pominięcie var nie deklaruje żadnej zmiennej, zamiast tego tworzy usuwalną właściwość na obiekcie globalnym, poza tym w trybie „użyj ścisłego” ES5 większość odpowiedzi jest oczywiście nieprawidłowa, niech też nie było Rozważyłem nawet tę odpowiedź, ponieważ w momencie pytania nie było żadnego odniesienia do wersji javascript (dodanej wczoraj), co sugerowałoby, że standardem odniesienia (w tym czasie) był ECMA 262 3. wydanie.
kentaromiura

43

Zawsze używaj varsłowa kluczowego do deklarowania zmiennych. Dlaczego? Dobra praktyka kodowania powinna być wystarczającym powodem sama w sobie, ale jej pominięcie oznacza, że ​​jest zadeklarowana w zasięgu globalnym (taka zmienna nazywana jest „domniemanym” globalnym). Douglas Crockford zaleca nigdy nie używać domyślnych globałów i zgodnie z wytycznymi Apple JavaScript Coding :

Każda zmienna utworzona bez var słowa kluczowego jest tworzona w zakresie globalnym i nie jest usuwana w przypadku, gdy funkcja powraca (ponieważ nie wykracza poza zakres), co stwarza możliwość wycieku pamięci.


17
„Dobra praktyka kodowania” nigdy nie powinna być wystarczającym powodem sama w sobie. Oznacza to, że „niektórzy faceci w Internecie powiedzieli, że tak powinien wyglądać mój kod”. Jest to nawet mniej ważne niż „powiedział mój nauczyciel”, chyba że ktoś choć trochę niejasno rozumie przyczynę tej reguły.
cHao

@ cHao Myślę, że good coding practicejest to zawsze wystarczający powód, jeśli jest to zalecana najlepsza praktyka, którą to jest i przez kilku autorów Javascript.
Chris S

8
@ChrisS: Nie, „dobra praktyka kodowania” nie jest sama w sobie powodem. Powodem jest to uważane za dobrą praktyką jest to, co się liczy. O ile ci autorzy nie powiedzą ci, dlaczego to zalecają, ich zalecenie nie powinno mieć żadnego znaczenia. Jeśli nie zgadzasz się z powodami, możesz uznać to za złą radę. A jeśli pójdziesz za tym, nie pytając dlaczego, tak zaczyna się kultywacja ładunków.
cHao

30

Oto całkiem dobry przykład, w jaki sposób można złapać się na tym, że nie deklarujemy zmiennych lokalnych za pomocą var:

<script>
one();

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

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

( ijest resetowany przy każdej iteracji pętli, ponieważ nie jest deklarowany lokalnie w forpętli, ale globalnie) ostatecznie skutkując nieskończoną pętlą


Yikes! Mogę sobie wyobrazić wszystkie błędy, które mogą być spowodowane przez tę literówkę.
BonsaiOak,

2
jestem ciekawy, dlaczego podajesz ja jako argument do two ()? (wewnątrz pętli for) czy to jest zbędne?
kalin

Argument jest ignorowany w funkcji two () zawartej w funkcji one (), ponieważ funkcja two () została zdefiniowana bez parametru. Masz całkowitą rację, nie jest to konieczne, ponieważ nie odgrywa roli.
KK.

Błąd czy funkcja?
TheMaster

13

Powiedziałbym, że lepiej jest używać varw większości sytuacji.

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

Jeśli nie użyjesz vardo deklarowania zmiennej, będzie ona miała zasięg globalny.

Aby uzyskać więcej informacji, możesz przeszukać „zakres łańcucha JavaScript” w Google.


Jeśli zadeklarujesz zmienną za pomocą słowa kluczowego var, zostanie ona utworzona w czasie wykonywania, więc czy nie powinna być wolniejsza? Ponieważ drugi jest tworzony w czasie analizy.
Barış Velioğlu

@RyuKaplan - hej, czy to prawda? Próbowałem google i nie mogłem uzyskać żadnych informacji na ten temat! Czy masz autorytet źródłowy dla tego stwierdzenia? Dzięki
gryzonie Mike

@RyuKaplan Parsowanie / kompilacja różni się od faktycznego uruchamiania kodu.
gcampbell

11

Nie używaj var!

varbył sposobem na deklarację zmiennej sprzed ES6. Jesteśmy teraz w przyszłości i powinieneś kodować jako taki.

Użyj constilet

constnależy stosować w 95% przypadków. Sprawia to, że odwołanie do zmiennej nie może się zmienić, a zatem właściwości tablicy, obiektu i węzła DOM mogą się zmienić i prawdopodobnie powinny const.

letnależy stosować dla każdej zmiennej, która ma zostać przypisana ponownie. Obejmuje to wewnątrz pętli for. Jeśli kiedykolwiek piszesz varName =poza inicjalizacją, użyj let.

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


2
Zamień wszystko, co „var” na „const” (zamień wszystko). Szybko zauważysz, gdzie są twoje przypisane zmienne. Jeśli masz ich zbyt wiele, prawdopodobnie kodujesz anty-wzorkowo: większość zmiennych, które można ponownie przypisać, mogą być osadzone w zamknięciach lub jako właściwości obiektu. Jeśli masz kilka: użyj dla nich opcji „let”. Wreszcie, jeśli niektóre zmienne nie zostaną w ogóle usunięte przez „var”, pozostaną niezgłoszone i nadal będą obecne w przestrzeni globalnej, strzeżcie się. O komentarzu @Gibolt „w pętli for” zaleca się również unikanie takich pętli w „95% przypadków” ;-): metody tablicowe są świetne.
allez l'OM

Mówiąc, że const należy stosować w 95% przypadków, wydaje się, że odchodzimy od dobrych praktyk i przechodzimy do dogmatów.
Agamemnus

9

inna różnica np

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

podczas

a = a || [] ; // a is undefined error.

1
Czy możesz wyjaśnić, dlaczego działa w przypadku zmiennej zdefiniowanej za pomocą „var” i zmiennej niezdefiniowanej za pomocą var? Czy zmienna jest tworzona przed oceną prawej strony przypisania w przypadku var?
mat

6
@Lucek, ponieważ var ajest podnoszony na szczyt zakresu i ustawiany na null, który deklaruje, ale nie inicjuje zmiennej, następnie w przypisaniu masz odwołanie do niezdefiniowanej zmiennej null, która zwraca wartość false, i ustaw przypisanie na []. W tym drugim przypadku masz przypisanie do właściwości anieruchomości a. Możesz przypisać do właściwości, która nie istnieje - tworząc ją przy przypisaniu, ale nie możesz czytać z właściwości, która nie istnieje bez ReferenceErrorrzucenia się na ciebie.
Evan Carroll,

1
@EvanCarroll: zostaje podniesiony do szczytu zakresu i ustawiony na niezdefiniowany zamiast zerowego.
mithunsatheesh

8

Używanie varjest zawsze dobrym pomysłem, aby zapobiec zaśmiecaniu zmiennych globalnego zasięgu, a konfliktom zmiennych powodując niechciane nadpisywanie.


8

Bez var- zmienna globalna.

Zdecydowanie zalecane ZAWSZE używaj varinstrukcji, ponieważ globalna zmienna init w kontekście lokalnym - jest zła. Ale jeśli potrzebujesz tej brudnej sztuczki, powinieneś napisać komentarz na początku strony:

/* global: varname1, varname2... */

3

Oto przykładowy kod, który napisałem, 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
Ta funkcja w żadnym wypadku nie jest „anonimowa”. W rzeczywistości jest tak widocznie nazwany, jak to tylko możliwe.
Ingo Bürk

Dziękujemy za edycję odpowiedzi w odpowiedzi na komentarz Ingo Bürka, aby „anonimowa funkcja” faktycznie była anonimowa.
Dave Burton,

3

@Chris S podał ładny przykład pokazujący praktyczną różnicę (i niebezpieczeństwo) pomiędzy vari nie var. Oto kolejny, uważam, że ten jest szczególnie niebezpieczny, ponieważ różnica jest widoczna tylko w środowisku asynchronicznym, dzięki czemu można go łatwo wymknąć podczas testowania.

Jak można oczekiwać, następujące dane wyjściowe fragmentu ["text"]:

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

console.log(var_fun())

Podobnie działa następujący fragment kodu (zwróć uwagę na brakujący letwcześniej array):

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

console.log(var_fun())

Asynchroniczne wykonywanie manipulacji danymi nadal daje ten sam wynik za pomocą jednego modułu wykonującego:

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żywając 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)})
})


Dzięki za przykład @thisismydesign! Jeśli chodzi o dwa ostatnie przykłady, dlaczego przedostatni przykład rejestruje tablicę 3 elementów trzykrotnie zapisanym tekstem, podczas gdy ostateczny przykład rejestruje „tekst” tylko raz na element w tablicy? (Rozumiem, że ostatni deklaruje „tablicę” jako zmienną i dlatego znajduje się w zasięgu lokalnym, podczas gdy przedostatni przykład tego pomija, czyniąc „tablicę” częścią dorozumianego zasięgu globalnego.) Ale dlaczego to wpływa na wynik? Czy dlatego, że forEach „i” iteruje po funkcji i wszystkich zmiennych globalnych?
AlmostPitt,

2

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

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

Dane wyjściowe będą czytane jako: false, false, true, true

Ponieważ postrzega zmienne w funkcji jako oddzielne od zmiennych spoza niej, stąd termin zmienna lokalna, a to dlatego, że użyliśmy zmiennej var w przypisaniu. Jeśli usuniesz zmienną var w funkcji, która teraz brzmi następująco:

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

Dane wyjściowe to false, false, false, false

Wynika to z faktu, że zamiast tworzyć nową zmienną w lokalnym zasięgu lub funkcji, po prostu używa zmiennych globalnych i ponownie przypisuje je do wartości false.


2

Widzę, że ludzie są zdezorientowani, kiedy deklarują zmienne z lub bez var i wewnątrz lub na zewnątrz funkcji. Oto głęboki przykład, który przeprowadzi Cię przez następujące 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 to, czy zadeklarowane z lub bez var (jak a, b), jeśli uzyskają swoją wartość poza funkcją, zachowają swoją wartość, a także wszelkie inne wartości dodane do różnych funkcji za pomocą skryptu zostaną zachowane.
  2. Jeśli zmienna zostanie zadeklarowana bez zmiennej wewnątrz funkcji (jak c), będzie działać jak poprzednia reguła, odtąd zachowa swoją wartość dla wszystkich funkcji. Albo uzyskała swoją pierwszą wartość w funkcji testVar1 (), 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 niezdefiniowana za każdym razem, gdy funkcja się zakończy. Będzie to zmienna tymczasowa w funkcji.

Dziękujemy za poświęcenie czasu na stworzenie przykładu do zademonstrowania tego tematu. W powyższym kodzie brakuje części poniżej, więc możesz zechcieć edytować swoją odpowiedź: a = 1; // Zdefiniowano poza funkcją bez var var b = 1; // Zdefiniowano poza funkcją z alertem var („Uruchamianie poza wszystkimi funkcjami ... \ n \ na, b zdefiniowane, ale c, d jeszcze nie zdefiniowane: \ na: "+ a +" \ nb: "+ b +" \ n \ n (Jeśli spróbuję wyświetlić wartość niezdefiniowanego c lub d, console.log zgłosi błąd „Uncaught ReferenceError: c nie jest zdefiniowany” błąd i skrypt przestanie działać!) ");
Sankofa,

1

Wewnątrz kodu, jeśli używasz zmiennej bez użycia var, wtedy automatycznie dzieje się, że var var_name jest umieszczane w zasięgu globalnym, 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

Oprócz kwestii zakresów, niektórzy wspominają również o podnoszeniu , ale nikt nie podał przykładu. Oto globalny zasięg:

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

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


0

Bez użycia zmiennych „var” można zdefiniować tylko po ustawieniu wartości. W przykładzie:

my_var;

nie może działać w zasięgu globalnym ani żadnym innym zakresie . Powinien mieć wartość taką jak:

my_var = "value";

Z drugiej strony możesz zdefiniować wartościowe polubienie;

var my_var;

Jego wartość to undefined(Jego wartość nie jest nulli nie jest równa nullinteresująco.).


my_var;jest właściwie prawidłową instrukcją wyrażenia.
Lexicore,

Jest to poprawna instrukcja, jeśli zmienna została wcześniej zdefiniowana. W przeciwnym razie generuje błąd „... nie jest zdefiniowany”.
umut

3
Jest to poprawna instrukcja, niezależnie od tego, czy zmienna została wcześniej zdefiniowana, czy nie. :) Poprawna instrukcja może zgłosić błąd, który nie unieważnia instrukcji .
leksykor

Jestem tym zmieszany. Co to jest ważne oświadczenie? Czy możesz podać przykład nieprawidłowego wyciągu?
umut

Będę musiał przeprosić - ostatnio za dużo gramatyki ECMAScript. my_var;jest prawidłową instrukcją wyrażenia . /my_var;byłoby niepoprawnym stwierdzeniem. Ale jak powiedziałem, to kazuistyka gramatyczna, przepraszam, mój komentarz był właściwie niewłaściwy.
Lexicore,

0

Powinieneś używać słowa kluczowego var, chyba że zamierzasz dołączyć zmienną do obiektu okna w przeglądarce. Oto link, który wyjaśnia zakres i różnicę między zasięgiem glocal a skalowaniem lokalnym za pomocą słowa kluczowego i bez słowa kluczowego var.

Kiedy zmienne są definiowane bez użycia słowa kluczowego var, to wygląda na prostą operację „przypisania”.

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

Możesz także spojrzeć na podnoszenie w javascript

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.