Kokia yra „JavaScript“ kintamųjų apimtis?

Kokia yra „JavaScript“ kintamųjų apimtis? Ar jie turi tą patį plotą viduje, o ne už funkcijos ribų? Ar tai netgi svarbu? Taip pat kur saugomi kintamieji, jei jie yra apibrėžti visame pasaulyje?

1742 m
01 февр. lYriCAlsSH rinkinys 01 vasaris 2009-02-01 11:27 '09 at 11:27 2009-02-01 11:27
@ 25 atsakymai

Manau apie tai, ką galiu padaryti, kad galėčiau jums pateikti keletą pavyzdžių. „Javascript“ programuotojai praktiškai vertinami pagal tai, kaip gerai jie supranta taikymo sritį. Jis kartais gali būti visiškai intuityvus.

  1. Kintamas su pasauliniu mastu

     // global scope var a = 1; function one() { alert(a); // alerts '1' } 
  2. Vietinė sritis

     // global scope var a = 1; function two(a) { // passing (a) makes it local scope alert(a); // alerts the given argument, not the global value of '1' } // local scope again function three() { var a = 3; alert(a); // alerts '3' } 
  3. Tarpinis : „JavaScript“ nėra tokio dalyko kaip blokinė sritis (ES5; ES6 let )

    a

     var a = 1; function four() { if (true) { var a = 4; } alert(a); // alerts '4', not the global value of '1' } 

    b.

     var a = 1; function one() { if (true) { let a = 4; } alert(a); // alerts '1' because the 'let' keyword uses block scoping } 
  4. Tarpinis : objekto savybės

     var a = 1; function Five() { this.a = 5; } alert(new Five().a); // alerts '5' 
  5. Neprivaloma : uždarymas

     var a = 1; var six = (function() { var a = 6; return function() { // JavaScript "closure" means I have access to 'a' in here, // because it is defined in the function in which I was defined. alert(a); // alerts '6' }; })(); 
  6. Neprivaloma : pagal prototipą pagrįsta rezoliucija

     var a = 1; function seven() { this.a = 7; } // [object].prototype.property loses to // [object].property in the lookup chain. For example... // Won't get reached, because 'a' is set in the constructor above. seven.prototype.a = -1; // Will get reached, even though 'b' is NOT set in the constructor. seven.prototype.b = 8; alert(new seven().a); // alerts '7' alert(new seven().b); // alerts '8' 

  7. „Global + Local“ : papildomas sunkus atvejis

     var x = 5; (function () { console.log(x); var x = 10; console.log(x); })(); 

    Tai bus išspausdinta undefined ir 10 vietoj 5 ir 10 nes „JavaScript“ visuomet perkelia kintamas deklaracijas (ne iniciacijas) į regiono viršų, o tai daro kodo ekvivalentą:

     var x = 5; (function () { var x; console.log(x); x = 10; console.log(x); })(); 
  8. Sugavimo kintamasis

     var e = 5; console.log(e); try { throw 6; } catch (e) { console.log(e); } console.log(e); 

    Tai atspausdins 5 , 6 , 5 . Paveiksle e objektas yra pasaulinių ir vietinių kintamųjų šešėliai. Tačiau ši speciali skalė skirta tik sužvejotam kintamajam. Jei rašote var f; viduje sugavimo sąlyga, ji yra lygiai tokia pati, kaip jei ją apibrėžėte prieš bandymo bloką arba po jo.

2292
01 февр. Atsakymą pateikė Triptych 01 Feb. 2009-02-01 11:58 '09 at 11:58 2009-02-01 11:58

„Javascript“ naudoja aprėpties grandines tam tikros funkcijos aprėpčiai nustatyti. Paprastai yra viena pasaulinė sritis, ir kiekviena apibrėžta funkcija turi savo lizdą. Bet kokioje kitoje funkcijoje apibrėžta funkcija turi vietinę zoną, susijusią su išorine funkcija. Tai visada yra šaltinis, kuris apibrėžia taikymo sritį.

Apimties grandinės elementas iš esmės yra žemėlapis su žymekliu į jo pagrindinę sritį.

border=0

Kai kintamasis yra įjungtas, javascript veikia vidinėje srityje ir ieško išorės.

221
01 февр. Atsakymas duotas krosenvold 01 Feb. 2009-02-01 11:35 '09 at 11:35 2009-02-01 11:35

Pasauliniu mastu deklaruojami kintamieji yra pasaulinio masto. Funkcijų deklaruoti kintamieji yra susieti su šia funkcija ir šešėliniais pasauliniais kintamaisiais, turinčiais tą patį pavadinimą.

(Esu įsitikinęs, kad yra daug subtilybių, kurios gali būti aprašytos kituose realių „JavaScript“ programuotojų atsakymuose. Visų pirma, aš šį puslapį susitikau apie tai, ką tai reiškia bet kuriuo metu. Tikiuosi, kad pakanka daugiau įvadinės nuorodos , kad galėtumėte pradėti dirbti .)

95
01 февр. Jon Skeet atsakymas 01 vasaris 2009-02-01 11:31 '09 11:31 val. 2009-02-01 11:31

Senosios mokyklos javascript

Tradiciškai „JavaScript“ tikrai turi tik dviejų tipų taikymo sritį:

  • Pasaulinis regionas . Kintamieji yra žinomi visoje paraiškoje, pradedant nuo paraiškos pateikimo momento (*)
  • Funkcinė sritis : kintamieji yra žinomi funkcijoje , kurioje jie yra deklaruojami, nuo funkcijos pradžios (*)

Aš to nedarysiu išsamiai, nes jau yra daug kitų atsakymų, paaiškinančių skirtumą.


Šiuolaikinis „JavaScript“

Paskutinės „JavaScript“ specifikacijos taip pat leidžia naudoti trečiąją sritį:

  1. Blokų skalė : kintamieji yra žinomi bloke , kuriuose jie yra paskelbti, nuo to momento, kai jie paskelbti į priekį (**)

Kaip sukurti blokines kintamas sritis?

Tradiciškai sukuriate savo kintamuosius taip:

 var myVariable = "Some text"; 

Užrakinti matomumo kintamieji yra sukurti taip:

 let myVariable = "Some text"; 

Koks skirtumas tarp funkcinės srities ir bloko dydžio?

Norėdami suprasti skirtumą tarp funkcinės srities ir bloko zonos, apsvarstykite šį kodą:

 // i IS NOT known here // j IS NOT known here // k IS known here, but undefined // l IS NOT known here function loop(arr) { // i IS known here, but undefined // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here for( var i = 0; i < arr.length; i++ ) { // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here }; // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here for( let j = 0; j < arr.length; j++ ) { // i IS known here, and has a value // j IS known here, and has a value // k IS known here, but has a value only the second time loop is called // l IS NOT known here }; // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here } loop([1,2,3,4]); for( var k = 0; k < arr.length; k++ ) { // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS NOT known here }; for( let l = 0; l < arr.length; l++ ) { // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS known here, and has a value }; loop([1,2,3,4]); // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS NOT known here 

Čia matome, kad mūsų kintamasis j žinomas tik pirmajame cikle, bet ne anksčiau, o ne vėliau. Tačiau mūsų kintamasis i žinomas per visą funkciją.

Be to, mano, kad prieš paskelbiant jų taikymo sritį kintamieji nežinomi, nes jie nėra iškelti. Taip pat neleidžiama perrašyti to paties kintamojo tame pačiame bloke esančiame regione. Tai lemia tai, kad kintamieji, turintys labai specializuotų sričių, yra mažiau linkę į klaidas nei visame pasaulyje arba funkciniu požiūriu nukopijuoti kintamieji, kurie kyla ir kurie nesukelia klaidų daugelio deklaracijų atveju.


Ar šiandien saugiai naudoti blokinius kintamuosius plotus?

Nepriklausomai nuo to, ar šiandien jis yra saugus, priklauso nuo jūsų aplinkos:

  • Jei rašote serverio („ Node.js“ ) „JavaScript“ kodą, galite saugiai naudoti leidimo pareiškimą.

  • Jei rašote kliento kodą ir naudojate transpiliatorių (pvz., „ Traceur“ ), galite saugiai naudoti leidimo pareiškimą, tačiau jūsų kodas greičiausiai bus optimalus našumo požiūriu.

  • Jei rašote kliento pusės kodą ir nenaudojate transpilerio, turite apsvarstyti naršyklės palaikymą.

    Šiandien, 2016 m. Vasario 23 d., Tai yra kai kurios naršyklės, kurios nepalaiko let arba turi tik dalinę paramą:

    • „Internet Explorer 10“ ir žemiau (be palaikymo)
    • „Firefox 43“ ir žemiau (be palaikymo)
    • Safari 9 ir žemiau (be palaikymo)
    • „Opera Mini 8“ ir žemiau (be palaikymo)
    • „Android“ naršyklė 4 ir žemiau (be palaikymo)
    • Opera 36 ir žemiau (dalinė parama)
    • „Chome 51“ ir žemiau (dalinė parama)

2019

23 февр. John Slegers atsakymas vasario 23 d 2016-02-23 21:51 '16 at 21:51 2016-02-23 21:51

Štai pavyzdys:

 <script> var globalVariable = 7; //==window.globalVariable function aGlobal( param ) { //==window.aGlobal(); //param is only accessible in this function var scopedToFunction = { //can't be accessed outside of this function nested : 3 //accessible by: scopedToFunction.nested }; anotherGlobal = { //global because there no `var` }; } </script> 

Jums reikia ištirti uždarymą ir naudoti juos privačių narių kūrimui.

35
01 февр. atsakymas pateikiamas geowa4 01 vasaris 2009-02-01 11:48 '09, 11:48 2009-02-01 11:48

Kaip suprantu, raktas yra tas, kad „Javascript“ apimtis ir platesnė „C“ domeno sritis.

Čia yra geras straipsnis apie šią temą.

28
15 мая '12 в 20:38 2012-05-15 20:38 James McMahon atsakė gegužės 15 d. 12 val. 2012-05-15 20:38

„Javascript 1.7“ („Mozilla“ plėtinys „Javascript“) taip pat galite deklaruoti tūrio regiono kintamuosius naudodami let pareiškimą :

  var a = 4; let (a = 3) { alert(a); // 3 } alert(a); // 4 
23
06 апр. Atsakymas pateikiamas kennytm 06 balandžio. 2010-04-06 14:19 '10 at 14:19 PM 2010-04-06 14:19

Idėja apibrėžti „JavaScript“ sritį, kai ją iš pradžių sukūrė „ Brendan Eich“, buvo paimta iš „ HyperCard“ scenarijų „ HyperTalk“ kalbos.

Šioje kalboje ekranai buvo panašūs į indekso kortelių krūvą. Buvo pagrindinė kortelė, vadinama fonu. Jis buvo skaidrus ir gali būti laikomas žemesne kortele. Bet koks šio pagrindinio žemėlapio turinys buvo bendrinamas su žemėlapiais, esančiais ant jo. Kiekviena ant viršaus įdėta kortelė turėjo savo turinį, kuris buvo viršesnis už ankstesnę kortelę, bet, jei pageidaujama, turėjo prieigą prie ankstesnių kortelių.

Taip sukurta „JavaScript“ peržiūros sistema. Jis tiesiog turi skirtingus pavadinimus. Žemėlapiai „JavaScript“ yra žinomi kaip ECMA vykdymo kontekstai . Kiekviename iš šių kontekstų yra trys pagrindinės dalys. Kintama aplinka, leksinė aplinka ir šis ryšys. Grįžtant prie žemėlapio nuorodos, leksinė aplinka apima visą turinį iš ankstesnių žemiau esančių žemėlapių. Dabartinis kontekstas yra viršuje, o bet koks ten deklaruotas turinys bus saugomas kintančioje aplinkoje. Kintančioji aplinka bus svarbesnė susidūrimo pavadinimų atveju.

Šis įrišimas bus nukreiptas į turinį. Kartais kontekstai arba vykdymo kontekstai keičiasi nekeičiant objekto objekto, pavyzdžiui, deklaruotos funkcijos, kur turintis objektas gali būti window arba konstruktorius.

Šie vykdymo kontekstai kuriami bet kuriuo metu. Valdymas perduodamas, kai kodas pradeda vykdyti, ir tai daugiausia atliekama vykdant funkciją.

Taigi tai yra techninis paaiškinimas. Praktiškai svarbu prisiminti, kad „JavaScript“

  • Laukai yra techniškai „vykdymo kontekstai“
  • Kontekstai sudaro aplinką, kurioje yra saugomi kintamieji.
  • Viršutinė viršuje yra pirmenybė (apačioje yra pasaulinis kontekstas)
  • Kiekviena funkcija sukuria vykdymo kontekstą (bet ne visada naują įpareigojimą)

Taikydami tai viename iš ankstesnių pavyzdžių (5. „Uždarymas“) šiame puslapyje, galite sekti vykdymo kontekstą. Šiame pavyzdyje stekoje yra trys kontekstai. Jie yra apibrėžiami išorės kontekste, kontekstą funkcijoje, kuri vadinama nedelsiant, vadinama var 6, ir kontekstą grąžinimo funkcijoje, esančioje funkcijoje var 6, skambina iš karto.

i) Išorinis kontekstas. Ji turi kintamą aplinką a = 1
ii) IIFE kontekste ji turi leksinę aplinką a = 1, bet kintama aplinka yra a = 6, kuri turi pirmenybę stekui iii) grąžinamas funkcijos kontekstas, jis turi leksinę aplinką a = 6, ir ši reikšmė yra nuoroda į perspėjimą apie skambutį.

2019

14 сент. Atsakymą pateikė Travis J 14 Sep. 2015-09-14 23:29 '15, 23:29 pm 2015-09-14 23:29

1) Ieškoma ir užfiksuota pasauliniu mastu, apimtis ir apimtis. Lygio kintamajame nėra „bloko“ lygio. Operatoriai su ir sugauti spausdina vardus savo blokuose.

2) Sritys yra prijungtos prie funkcijų iki pasaulio.

3) Savybės išsprendžiamos pro prototipo grandinę. Su pareiškimu su objektu priskiriami objekto savybių pavadinimai leksinei sričiai, nurodytai bloke c.

EDIT: ECMAAScript 6 (Harmonija) siūloma palaikyti, ir aš žinau, kad chromui leidžiama „harmonijos“ vėliava, taigi gal ji ją palaiko.

Leiskite palaikyti bloko lygio nustatymą, tačiau jums reikia naudoti raktinį žodį taip, kad jis įvyktų.

EDIT: Remdamasis tuo, kad Benjaminas atkreipė dėmesį į komentarus ir komentarus, redagavau pranešimą ir pridėjau daugiau. Tiek su, tiek sugauti apibrėžti kintamieji jų atitinkamuose blokuose, ir tai yra bloko sritis. Šie kintamieji yra jiems perduotų objektų savybių pseudonimas.

  //chrome (v8) var a = { 'test1':'test1val' } test1 // error not defined with (a) { var test1 = 'replaced' } test1 // undefined a // a.test1 = 'replaced' 

EDIT: Pavyzdžio paaiškinimas:

test1 yra susietas su c bloku, bet lyginamas su a.test1. „Var test1“ sukuria naują test1 kintamąjį viršutiniame leksiniame kontekste (funkcija arba pasaulinė), nebent tai yra nuosavybė a, kuri ji yra.

Clap! Būkite atsargūs, naudodami „su“ - kaip ir var noop, jei kintamasis jau yra apibrėžtas funkcijoje, jis taip pat yra iš pavadinimų, importuotų iš objekto! Mažai galvos ant jau apibrėžto pavadinimo būtų daug saugiau. Dėl to aš asmeniškai niekada jo nenaudosiu.

16
25 окт. Gerard ONeill atsakymas spalio 25 d. 2013-10-25 03:41 '13, 3:41, 2013-10-25 03:41

Radau, kad daugelis žmonių, kurie nėra susipažinę su „JavaScript“, nesupranta, kad paveldėjimas yra numatytas pagal kalbą, o galimybių apimtis yra vienintelė sritis. Suteikiau pratęsimą „beautifier“, kurį praėjusių metų pabaigoje parašiau „JSPretty“. Funkcijos spalvos funkcijos funkcija kode ir visada susieja visų šioje srityje deklaruojamų kintamųjų spalvą. Uždarymas vizualiai parodomas, kai kitoje srityje naudojamas kintamasis, kurio spalva yra iš vienos srities.

Pabandykite naudoti šią funkciją:

Žr. Demonstraciją:

Peržiūrėkite kodą adresu:

Šiuo metu ši funkcija palaiko 16 įdėtų funkcijų gylį, bet šiuo metu nėra spalvotų pasaulinių kintamųjų.

9
21 марта '13 в 20:31 2013-03-21 20:31 atsakymas pateikiamas austincheney kovo 21 d., 13:20, 2013-03-21 20:31

Norėdami pridėti kitų atsakymų, taikymo sritis yra visų deklaruotų identifikatorių (kintamųjų) sąrašas ir taikoma griežta taisyklių rinkinys, kaip jie yra prieinami dabartiniam kodui. Ši paieška gali būti sukurta priskirti kintamąjį, kuris yra LHS nuoroda (kairėje pusėje), arba gali būti naudojamas jo vertei, kuri yra RHS nuoroda (dešinėje). Šie vaizdai yra tai, ką „JavaScript“ variklis daro viduje, kai jis rengia ir vykdo kodą.

Taigi, šiuo požiūriu, manau, kad nuotrauka padės tai, ką radau knygoje „Apimtis ir uždarymas Kyle Simpson“:

2019

„JavaScript“ turi tik dviejų tipų taikymo sritį:

  • Pasaulinis mastas . „Global“ yra tik >
  • Funkcinė sritis . Kintamasis, deklaruotas funkcijoje su var raktiniu žodžiu, turi funkcinę sritį.

Kai yra vadinama funkcija, sukuriamas kintamojo ploto objektas (įtraukiamas į taikymo srities grandinę), po kurio seka kintamieji „JavaScript“.

  a = "global"; function outer(){ b = "local"; console.log(a+b); //"globallocal" } outer(); 

Grandinės regionas →

  • >a ir outer funkcijos yra viršutiniame lygyje.
  • kai išorinė funkcija, vadinama nauju variable scope object (ir įtraukta į variable scope object grandinę), yra pridėta su kintamuoju b viduje.

Dabar, kai kintamasis a reikalauja, kad jis pirmiausia ieškotų artimiausio kintamo regiono, o jei kintamasis neegzistuoja, jis pereina į kitą kintamą grandinės objektą. Šiuo atveju tai yra >

8
21 сент. Anshul atsakymas 21 rugsėjis 2014-09-21 23:44 '14, 23:44 2014-09-21 23:44

Pasaulinis mastelis:

Pasauliniai kintamieji yra lygiai taip pat, kaip pasaulinės žvaigždės (Jackie Chan, Nelson Mandela). Jiems galite pasiekti (gauti arba nustatyti vertę) iš bet kurios programos dalies. Pasaulinės funkcijos yra panašios į pasaulinius įvykius (Naujieji metai, Kalėdos). Galite atlikti (skambinti) juos iš bet kurios programos dalies.

 //global variable var a = 2; //global function function b(){ console.log(a); //access global variable } 

Vietovė:

Jei esate JAV, galite atpažinti Kim Kardashian, liūdnai garsėjančią garsenybę (ji kažkaip sugeba padaryti bulvarinius). Tačiau žmonės už Jungtinių Amerikos Valstijų jos nepripažįsta. Ji yra vietinė žvaigždė, susieta su jos teritorija.

Vietiniai kintamieji yra panašūs į vietines žvaigždes. Jiems galite pasiekti (gauti arba nustatyti vertę) rajone. Vietinė funkcija panaši į vietinius įvykius - galite atlikti (švęsti) tik šioje srityje. Jei norite prieiti prie jų iš išorės, gausite nuorodos klaidą.

 function b(){ var d = 21; //local variable console.log(d); function dog(){ console.log(a); } dog(); //execute local function } console.log(d); //ReferenceError: dddddd is not defined 

Išsiaiškinkite šio straipsnio išsamų supratimą apie šį straipsnį

7
24 июня '14 в 17:12 2014-06-24 17:12 atsakymą įteikė KhanSharp , birželio 24 d. 14 d., 17:12, 2014-06-24 17:12

paleiskite kodą. Tikiuosi, kad tai suteiks idėją apie taikymo sritį

 Name = 'global data'; document.Name = 'current document data'; (function(window,document){ var Name = 'local data'; var myObj = { Name: 'object data', f: function(){ alert(this.Name); } }; myObj.newFun = function(){ alert(this.Name); } function testFun(){ alert("Window Scope : " + window.Name + "\nLocal Scope : " + Name + "\nObject Scope : " + this.Name + "\nCurrent document Scope : " + document.Name ); } testFun.call(myObj); })(window,document); 
7
18 окт. Yeasin Abedin Siam atsakymas spalio 18 d 2014-10-18 12:54 '14, 12:54 2014-10-18 12:54

Šiuolaikiniai Js, ES6 +, „ const “ ir „ let

Kiekvienam sukuriamam kintamajam turite naudoti peržiūros sritį, kaip ir daugelis kitų pagrindinių kalbų. var yra pasenęs . Dėl to jūsų kodas yra saugesnis ir patogesnis.

const turėtų būti naudojamas 95% atvejų . Tai leidžia, kad pamatinis kintamasis negalėtų keistis. Masyvo, objekto ir DOM mazgo savybės gali keistis ir tikriausiai turėtų būti const .

let naudoti bet kokiam kintamajam laukiant kintamojo keitimo. Tai apima kilpą. Jei pakeisite reikšmę, esančią už inicijavimo, naudokite let .

Blokų sritis reiškia, kad kintamasis bus prieinamas tik skliausteliuose, kuriuose jis yra deklaruojamas. Это распространяется на внутренние области, включая анонимные функции, созданные в вашей области.

5
ответ дан Gibolt 26 сент. '17 в 23:23 2017-09-26 23:23