Wat is het bereik van variabelen in JavaScript?

Wat is het bereik van variabelen in javascript? Hebben ze hetzelfde bereik binnen als buiten een functie? Of maakt het zelfs uit? En waar worden de variabelen opgeslagen als ze globaal zijn gedefinieerd?


Antwoord 1, autoriteit 100%

TLDR

JavaScript heeft lexicale (ook wel statische) scoping en sluitingen genoemd. Dit betekent dat je de reikwijdte van een identifier kunt zien door naar de broncode te kijken.

De vier bereiken zijn:

  1. Globaal – overal zichtbaar
  2. Functie – zichtbaar binnen een functie (en zijn subfuncties en blokken)
  3. Blok – zichtbaar binnen een blok (en zijn subblokken)
  4. Module – zichtbaar binnen een module

Buiten de speciale gevallen van globaal en modulebereik, worden variabelen gedeclareerd met behulp van var(functiebereik), let(blokbereik) en const(blokbereik). De meeste andere vormen van ID-declaratie hebben een blokbereik in de strikte modus.

Overzicht

Omvang is de regio van de codebase waarover een identifier geldig is.

Een lexicale omgeving is een koppeling tussen identifier-namen en de bijbehorende waarden.

Het bereik wordt gevormd door een gekoppelde nesting van lexicale omgevingen, waarbij elk niveau in de nesting overeenkomt met een lexicale omgeving van een voorouderuitvoeringscontext.

Deze gekoppelde lexicale omgevingen vormen een scope “keten”. Identifier-resolutie is het proces van zoeken langs deze keten naar een overeenkomende identifier.

Identificatieresolutie vindt slechts in één richting plaats: naar buiten. Op deze manier kunnen uiterlijke lexicale omgevingen niet “zien” in innerlijke lexicale omgevingen.

Er zijn drie relevante factoren bij het bepalen van de scopevan een identificatiein JavaScript:

  1. Hoe een ID is gedeclareerd
  2. Waar een ID is gedeclareerd
  3. Of je nu in de strikte modusof niet-strikte modus

Enkele manieren waarop identifiers kunnen worden gedeclareerd:

  1. var, leten const
  2. Functieparameters
  3. Vangblokparameter
  4. Functieverklaringen
  5. Benoemde functie-uitdrukkingen
  6. Impliciet gedefinieerde eigenschappen voor het globale object (d.w.z. het missen van varin niet-strikte modus)
  7. importverklaringen
  8. eval

Sommige locatie-ID’s kunnen worden gedeclareerd:

  1. Wereldwijde context
  2. Functietekst
  3. Gewoon blok
  4. De bovenkant van een controlestructuur (bijv. lus, if, while, etc.)
  5. Besturingsstructuur lichaam
  6. Modules

Declaratiestijlen

var

Identifiers gedeclareerd met varhebben functiebereik, behalve wanneer ze direct in de globale context worden gedeclareerd, in welk geval ze worden toegevoegd als eigenschappen aan het globale object en wereldwijde reikwijdte hebben. Er zijn aparte regels voor het gebruik ervan in eval-functies.

let en const

Identifiers gedeclareerd met leten consthebben een block scope, behalve wanneer ze direct in de globale context worden gedeclareerd, in welk geval ze hebben een wereldwijde reikwijdte.

Opmerking: let, consten varworden allemaal gehesen. Dit betekent dat hun logische positie van definitie de top is van hun omsluitende scope (blok of functie). Variabelen die zijn gedeclareerd met behulp van leten constkunnen echter niet worden gelezen of toegewezen totdat de besturing het declaratiepunt in de broncode is gepasseerd. De tussentijdse periode staat bekend als de tijdelijke dode zone.

function f() {
    function g() {
        console.log(x)
    }
    let x = 1
    g()
}
f() // 1 because x is hoisted even though declared with `let`!

Antwoord 2, autoriteit 9%

Javascript gebruikt bereikketens om het bereik voor een bepaalde functie vast te stellen. Er is meestal één globaal bereik en elke gedefinieerde functie heeft zijn eigen geneste bereik. Elke functie die binnen een andere functie is gedefinieerd, heeft een lokaal bereik dat is gekoppeld aan de buitenste functie. Het is altijd de positie in de bron die het bereik bepaalt.

Een element in de bereikketen is in feite een kaart met een verwijzing naar het bovenliggende bereik.

Bij het oplossen van een variabele begint javascript bij het binnenste bereik en zoekt het naar buiten.


Antwoord 3, autoriteit 4%

Globaal gedeclareerde variabelen hebben een globaal bereik. Variabelen die binnen een functie zijn gedeclareerd, vallen onder die functie en schaduwen globale variabelen met dezelfde naam.

(Ik weet zeker dat er veel subtiliteiten zijn waar echte JavaScript-programmeurs in andere antwoorden op kunnen wijzen. In het bijzonder kwam ik deze paginaover wat thisprecies betekent op elk moment. Hopelijk deze meer inleidende linkis echter voldoende om u op weg te helpen.)


Antwoord 4, autoriteit 3%

Oude school JavaScript

Traditioneel heeft JavaScript eigenlijk maar twee soorten bereik:

  1. Globaal bereik: variabelen zijn bekend in de hele applicatie, vanaf het begin van de applicatie (*)
  2. Functioneel bereik: variabelen zijn bekend binnen de functiewaarin ze zijn gedeclareerd, vanaf het begin van de functie (*)

Ik zal hier niet verder op ingaan, aangezien er al veel andere antwoorden zijn die het verschil uitleggen.


Modern JavaScript

De meest recente JavaScript-specificatiesnu ook een derde bereik toestaan:

  1. Block Scope: Identifiers zijn “bekend” vanaf de bovenkant van het bereik waarin ze zijn gedeclareerd, maar ze kunnen pas na de regel van hun aangifte worden toegewezen aan of worden verwijderd (gelezen). Deze tussenperiode wordt de “tijdelijke dode zone” genoemd.

Hoe maak ik blokbereikvariabelen?

Traditioneel maakt u uw variabelen als volgt:

var myVariable = "Some text";

Blokbereikvariabelen worden als volgt gemaakt:

let myVariable = "Some text";

Dus wat is het verschil tussen functioneel bereik en blokbereik?

Beschouw de volgende code om het verschil tussen functioneel bereik en blokbereik te begrijpen:

// 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

Hier kunnen we zien dat onze variabele jalleen bekend is in de eerste for-lus, maar niet ervoor en erna. Toch is onze variabele ibekend in de hele functie.

Houd er ook rekening mee dat variabelen met een blokbereik niet bekend zijn voordat ze worden gedeclareerd, omdat ze niet worden gehesen. Het is ook niet toegestaan om dezelfde variabele binnen hetzelfde blok opnieuw te declareren. Dit maakt block scoped variabelen minder foutgevoelig dan globale of functioneel scoped variabelen, die worden gehesen en die geen fouten produceren in het geval van meerdere declaraties.


Is het veilig om vandaag blokbereikvariabelen te gebruiken?

Of het vandaag veilig is om te gebruiken, hangt af van uw omgeving:

  • Als u server-side JavaScript-code schrijft (Node.js), kunt u veilig het letstatement gebruiken.

  • Als u JavaScript-code aan de clientzijde schrijft en een browsergebaseerde transpiler gebruikt (zoals Traceurof babel-standalone), kunt u veilig de let-instructie gebruiken, maar uw code is waarschijnlijk allesbehalve optimaal met betrekking tot prestaties.

  • Als u client-side JavaScript-code schrijft en een op Node gebaseerde transpiler gebruikt (zoals de traceur-shellscriptof Babel), kunt u veilig het letstatement gebruiken. En omdat uw browser alleen weet van de getranspileerde code, moeten prestatienadelen worden beperkt.

  • Als u client-side JavaScript-code schrijft en geen transpiler gebruikt, moet u browserondersteuning overwegen.

    Dit zijn enkele browsers die lethelemaal niet ondersteunen:

    • Internet Explorer 10en lager
    • Firefox 43en lager
    • Safari 9en lager
    • Android-browser 4en lager
    • Opera 27en lager
    • Chome 40en lager
    • ELKE versie van Opera Mini& Blackberry-browser


Browserondersteuning bijhouden

Voor een actueel overzicht van welke browsers het letstatement ondersteunen op het moment dat je dit antwoord leest, zie deze Can I Usepagina.


(*) Globaal en functioneel bereikbare variabelen kunnen worden geïnitialiseerd en gebruikt voordat ze worden gedeclareerd, omdat JavaScript-variabelen gehesen.Dit betekent dat declaraties altijd veel belangrijker zijn.


Antwoord 5, autoriteit 2%

Hier is een voorbeeld:

<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's no `var`
  }; 
}
</script>

U zult sluitingen willen onderzoeken en hoe u deze kunt gebruiken om privéleden.


Antwoord 6

De sleutel, zoals ik het begrijp, is dat Javascript scoping op functieniveau heeft versus de meer gebruikelijke scoping van C-blokken.

Hier is een goed artikel over dit onderwerp.


Antwoord 7

In “Javascript 1.7” (Mozilla’s extensie voor Javascript) kan men ook block-scope variabelen declareren met letstatement:

var a = 4;
 let (a = 3) {
   alert(a); // 3
 }
 alert(a);   // 4

Antwoord 8

Het idee van scoping in JavaScript wanneer oorspronkelijk is ontworpen door Brendan eich kwam uit de Inpercard scripting taal hypertalk .

In deze taal werden de displays op een stapel indexkaarten uitgevoerd. Er werd een meesterkaart genoemd als de achtergrond. Het was transparant en kan worden gezien als de onderste kaart. Elke inhoud op deze basiskaart werd gedeeld met kaarten die er bovenop worden geplaatst. Elke kaart die bovenop werd geplaatst, had zijn eigen inhoud die de voorrang heeft gedaan over de vorige kaart, maar had nog steeds toegang tot de eerdere kaarten indien gewenst.

Dit is precies hoe het JavaScript Scoping-systeem is ontworpen. Het heeft gewoon verschillende namen. De kaarten in JavaScript staan ​​bekend als uitvoering contexten ECMa . Elk van deze contexten bevat drie hoofdonderdelen. Een variabele omgeving, een lexicale omgeving en een deze binding. Teruggaan naar de referentie van de kaarten, bevat de lexicale omgeving alle inhoud van de lager van de vorige kaarten in de stapel. De huidige context bevindt zich bovenaan de stapel en alle gedeclareerde inhoud wordt opgeslagen in de variabele omgeving. De variabele omgeving zal voorrang hebben in het geval van het benoemen van botsingen.

De deze binding wijzen op het bevattende object. Soms veranderen scopes of uitvoeringcontents zonder het bevattende object dat verandert, zoals in een aangegeven functie waarbij het bevattende object windowof een constructor-functie mogelijk is.

Deze uitvoeringscontexten worden op elk momentcontrole gemaakt, wordt overgedragen. De besturing wordt overgedragen wanneer de code begint uit te voeren en dit wordt voornamelijk uitgevoerd uit de uitvoering van de functie.

Dus dat is de technische uitleg. In de praktijk is het belangrijk om te onthouden dat in JavaScript

  • Scopes zijn technisch gezien “uitvoeringscontexten”
  • Contexten vormen een stapel omgevingen waarin variabelen worden opgeslagen
  • De bovenkant van de stapel heeft voorrang (de onderkant is de globale context)
  • Elke functie creëert een uitvoeringscontext (maar niet altijd een nieuwe deze binding)

Als je dit toepast op een van de voorgaande voorbeelden (5. “Sluiting”) op deze pagina, is het mogelijk om de stapel uitvoeringscontexten te volgen. In dit voorbeeld zijn er drie contexten in de stapel. Ze worden gedefinieerd door de buitenste context, de context in de onmiddellijk aangeroepen functie die wordt aangeroepen door var zes, en de context in de geretourneerde functie binnen de onmiddellijk aangeroepen functie van var zes.

i) De uiterlijke context. Het heeft een variabele omgeving van a = 1
ii) De IIFE-context heeft een lexicale omgeving van a = 1, maar een variabele omgeving van a = 6 die voorrang heeft in de stapel
iii) De geretourneerde functiecontext heeft een lexicale omgeving van a = 6 en dat is de waarde waarnaar in de waarschuwing wordt verwezen wanneer deze wordt aangeroepen.


Antwoord 9

1) Er is een globaal bereik, een functiebereik en het bereik met en vangst. Er is in het algemeen geen bereik op ‘blok’-niveau voor variabelen — de with en de catch-statements voegen namen toe aan hun blokken.

2) Bereiken zijn genest door functies tot aan het globale bereik.

3) Eigenschappen worden opgelost door de prototypeketen te doorlopen. Het with statement brengt objecteigenschapsnamen in het lexicale bereik gedefinieerd door het with blok.

EDIT: ECMAAScript 6 (Harmony) is gespecificeerd om let te ondersteunen, en ik weet dat Chrome een ‘harmony’-vlag toestaat, dus misschien ondersteunt het dit wel..

Laten we een ondersteuning zijn voor scoping op blokniveau, maar je moet het trefwoord gebruiken om het mogelijk te maken.

BEWERKEN: Gebaseerd op Benjamin’s verwijzing naar de met en catch-statements in de opmerkingen, heb ik de post bewerkt en meer toegevoegd. Zowel de with- als de catch-statements introduceren variabelen in hun respectievelijke blokken, en dat iseen blokbereik. Deze variabelen zijn gekoppeld aan de eigenschappen van de objecten die erin worden doorgegeven.

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

EDIT: verduidelijkend voorbeeld:

test1 valt binnen het bereik van het with-blok, maar heeft een alias naar a.test1. ‘Var test1’ creëert een nieuwe variabele test1 in de bovenste lexicale context (functie, of globaal), tenzij het een eigenschap is van a — wat het is.

Ja maar! Wees voorzichtig met het gebruik van ‘with’ — net zoals var een noop is als de variabele al in de functie is gedefinieerd, is het ook een noop met betrekking tot namen die uit het object zijn geïmporteerd! Een beetje op de hoogte van de naam die al is gedefinieerd, zou dit veel veiliger maken. Persoonlijk zal ik dit daarom nooit gebruiken.


Antwoord 10

Ik ontdekte dat veel mensen die nieuw zijn in JavaScript, moeite hebben om te begrijpen dat overerving standaard beschikbaar is in de taal en dat functiebereik tot nu toe het enige bereik is. Ik heb een uitbreiding gegeven op een verfraaiing die ik eind vorig jaar heb geschreven, genaamd JSPretty. De functiekleuren functie bereik in de code en koppelt altijd een kleur aan alle variabelen die in dat bereik zijn gedeclareerd. Sluiting wordt visueel gedemonstreerd wanneer een variabele met een kleur uit het ene bereik wordt gebruikt in een ander bereik.

Probeer de functie op:

Bekijk een demo op:

Bekijk de code op:

Momenteel biedt de functie ondersteuning voor een diepte van 16 geneste functies, maar kleurt momenteel geen globale variabelen.


Antwoord 11

JavaScript heeft slechts twee soorten bereik:

  1. Globaal bereik: Globaal is niets anders dan een bereik op vensterniveau. Hier, variabele aanwezig in de hele applicatie.
  2. Functioneel bereik: Variabele gedeclareerd binnen een functie met het trefwoord varheeft een functioneel bereik.

Telkens wanneer een functie wordt aangeroepen, wordt een variabel bereikobject gemaakt (en opgenomen in de bereikketen), gevolgd door variabelen in JavaScript.

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

Scope-keten –>

  1. Vensterniveau – aen outerfunctie bevinden zich op het hoogste niveau in de scopeketen.
  2. wanneer buitenste functie een nieuw variable scope objectaanroept (en opgenomen in bereikketen) toegevoegd met variabele berin.

Als een variabele anu vereist is, zoekt deze eerst naar het dichtstbijzijnde variabele bereik en als de variabele er niet is, gaat het naar het volgende object van de variabele bereikketen. In dit geval is dat op vensterniveau.


Antwoord 12

voer de code uit. hoop dat dit een idee geeft over scoping

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

Antwoord 13

Globaal bereik:

Globale variabelen zijn precies hetzelfde als de wereldwijde sterren (Jackie Chan, Nelson Mandela). Je kunt ze toegang krijgen tot (te krijgen of de waarde), uit alle delen van uw aanvraag. Global functies zijn zoals gebeurtenissen in de wereld (Nieuwjaar, Kerstmis). U kunt uitvoeren (call) hen van een deel van uw applicatie.

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

Local Scope:

Als je in de Verenigde Staten, kunt u weet Kim Kardashian, berucht beroemdheid (ze een of andere manier erin slaagt om de tabloids te maken). Maar mensen buiten de VS zal haar niet herkennen. Ze is een lokale ster, gebonden aan haar grondgebied.

Lokale variabelen zijn als lokale sterren. U kunt ze alleen toegang krijgen (of de waarde) binnen de scope. Een lokale functie is als lokale evenementen – u kunt uitvoeren alleen (vieren) in die ruimte. Als je ze wilt toegang van buiten de scope, zal je een referentie fout

krijgen

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    

Controleer dit artikel voor diepgaand begrip van het werkterrein


14

Om aan de andere antwoorden toe te voegen, scope is een opzoeklijst van alle gedeclareerde identifiers (variabelen), en dwingt een strikte set regels af over hoe deze toegankelijk zijn voor de code die momenteel wordt uitgevoerd. Deze look-up kan zijn voor het toewijzen aan de variabele, wat een LHS-referentie (links) is, of het kan zijn voor het ophalen van de waarde ervan, wat een RHS-referentie (rechts) is. Deze opzoekingen zijn wat de JavaScript-engine intern doet tijdens het compileren en uitvoeren van de code.

Dus vanuit dit perspectief denk ik dat een foto zou helpen die ik vond in het e-boek Scopes and Closures van Kyle Simpson:

Citaat uit zijn e-boek:

Het gebouw vertegenwoordigt de geneste scope-regelset van ons programma. De eerste
verdieping van het gebouw vertegenwoordigt uw huidige uitvoeringsbereik,
waar je ook bent. Het hoogste niveau van het gebouw is de globale scope.
U lost LHS- en RHS-referenties op door op uw huidige verdieping te kijken,
en als je het niet vindt, neem dan de lift naar de volgende verdieping,
daar kijken, dan de volgende, enzovoort. Als je eenmaal op de bovenste verdieping bent
(het globale bereik), ofwel vindt u wat u zoekt, of u
niet doen. Maar je moet hoe dan ook stoppen.

Eén ding dat het vermelden waard is: “Het zoeken naar bereik stopt zodra het de eerste overeenkomst heeft gevonden”.

Dit idee van ‘bereikniveaus’ verklaart waarom ‘dit’ kan worden gewijzigd met een nieuw gemaakt bereik, als het wordt opgezocht in een geneste functie.
Hier is een link die ingaat op al deze details, Alles wat je wilde om meer te weten te komen over het bereik van javascript


Antwoord 15

Er zijn BIJNA slechts twee soorten JavaScript-bereiken:

  • het bereik van elke var-declaratie is gekoppeld aan de meest direct omsluitende functie
  • als er geen omsluitende functie is voor een var-declaratie, is het een globale scope

Dus alle andere blokken dan functies creëren geen nieuw bereik. Dat verklaart waarom for-loops variabelen met een buitenbereik overschrijven:

var i = 10, v = 10;
for (var i = 0; i < 5; i++) { var v = 5; }
console.log(i, v);
// output 5 5

In plaats daarvan functies gebruiken:

var i = 10, v = 10;
$.each([0, 1, 2, 3, 4], function(i) { var v = 5; });
console.log(i,v);
// output 10 10

In het eerste voorbeeld was er geen blokbereik, dus de aanvankelijk gedeclareerde variabelen werden overschreven. In het tweede voorbeeld was er een nieuwe scope vanwege de functie, dus de aanvankelijk gedeclareerde variabelen waren SHADOWED en niet overschreven.

Dat is bijna alles wat u moet weten over JavaScript-scoping, behalve:

Je kunt dus zien dat JavaScript-scoping eigenlijk heel eenvoudig is, hoewel niet altijd intuïtief. Een paar dingen om op te letten:

  • var-declaraties worden naar de top van de scope gehesen. Dit betekent dat het niet uitmaakt waar de var-declaratie plaatsvindt, voor de compiler is het alsof de var zelf bovenaan plaatsvindt
  • meerdere var-declaraties binnen hetzelfde bereik worden gecombineerd

Dus deze code:

var i = 1;
function abc() {
  i = 2;
  var i = 3;
}
console.log(i);     // outputs 1

is gelijk aan:

var i = 1;
function abc() {
  var i;     // var declaration moved to the top of the scope
  i = 2;
  i = 3;     // the assignment stays where it is
}
console.log(i);

Dit lijkt misschien contra-intuïtief, maar het is logisch vanuit het perspectief van een imperatieve taalontwerper.


Antwoord 16

Moderne Js, ES6+, ‘const‘ en ‘let

Je zou block scoping moeten gebruiken voor elke variabele die je maakt, net als de meeste andere belangrijke talen. varis verouderd. Dit maakt je code veiliger en beter te onderhouden.

constmoet in 95% van de gevallenworden gebruikt. Het zorgt ervoor dat de variabele referentieniet kan veranderen. Eigenschappen van array, object en DOM-knooppunt kunnen veranderen en moeten waarschijnlijk constzijn.

letmoet worden gebruikt voor elke variabele die verwacht opnieuw te worden toegewezen. Dit omvat binnen een for-lus. Als je ooit de waarde verandert na de initialisatie, gebruik dan let.

Block scope betekent dat de variabele alleen beschikbaar is tussen de haakjes waarin deze is gedeclareerd. Dit geldt ook voor interne scopes, inclusief anonieme functies die binnen uw scope zijn gemaakt.


Antwoord 17

Inline-handlers

Een veel voorkomend probleem dat nog niet is beschreven en waar front-end codeurs vaak tegenaan lopen, is het bereik dat zichtbaar is voor een inline event-handler in de HTML – bijvoorbeeld met

<button onclick="foo()"></button>

Het bereik van de variabelen waarnaar een on*-attribuut kan verwijzen moetzijn:

  • globaal (werkende inline-handlers verwijzen bijna altijd naar globale variabelen)
  • een eigenschap van het document (bijv. querySelectorals zelfstandige variabele verwijst naar document.querySelector; zeldzaam)
  • een eigenschap van het element waaraan de handler is gekoppeld (zoals hierboven; zeldzaam)

Anders krijg je een ReferenceError wanneer de handler wordt aangeroepen. Dus, bijvoorbeeld, als de inline-handler verwijst naar een functie die is gedefinieerd inwindow.onloadof $(function() {, de verwijzing zal mislukken, omdat de inline-handler alleen mag verwijzen naar variabelen in het globale bereik en de functie niet globaal is:


Antwoord 18

Probeer dit merkwaardige voorbeeld. In het onderstaande voorbeeld, als a een numeriek geïnitialiseerd op 0 was, zou je 0 en dan 1 zien. Behalve dat a een object is en javascript f1 een aanwijzer van a zal doorgeven in plaats van een kopie ervan. Het resultaat is dat u beide keren dezelfde melding krijgt.

var a = new Date();
function f1(b)
{
    b.setDate(b.getDate()+1);
    alert(b.getDate());
}
f1(a);
alert(a.getDate());

Antwoord 19

Er zijn alleen functiebereiken in JS. Blokkeer geen scope!
Je kunt ook zien wat er wordt gehesen.

var global_variable = "global_variable";
var hoisting_variable = "global_hoist";
// Global variables printed
console.log("global_scope: - global_variable: " + global_variable);
console.log("global_scope: - hoisting_variable: " + hoisting_variable);
if (true) {
    // The variable block will be global, on true condition.
    var block = "block";
}
console.log("global_scope: - block: " + block);
function local_function() {
    var local_variable = "local_variable";
    console.log("local_scope: - local_variable: " + local_variable);
    console.log("local_scope: - global_variable: " + global_variable);
    console.log("local_scope: - block: " + block);
    // The hoisting_variable is undefined at the moment.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);
    var hoisting_variable = "local_hoist";
    // The hoisting_variable is now set as a local one.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);
}
local_function();
// No variable in a separate function is visible into the global scope.
console.log("global_scope: - local_variable: " + local_variable);

20

Mijn begrip is dat er 3 scopes zijn: wereldwijde reikwijdte, wereldwijd beschikbaar; Lokale reikwijdte, beschikbaar voor een volledige functie, ongeacht blokken; en blokkoper, alleen beschikbaar voor het blok, verklaring of uitdrukking waarop het werd gebruikt. Globale en lokale reikwijdte worden aangegeven met het trefwoord ‘var’, hetzij binnen een functie of buiten- en blokkoper wordt aangegeven met het trefwoord ‘laat’.

Voor degenen die geloven dat er slechts wereldwijde en lokale reikwijdte is, leg dan uit waarom Mozilla een hele pagina zou hebben die de nuances van blokkoper in JS beschrijft.

https://developer.mozilla.org / NL-VS / DOCS / WEB / JAVASSCRIPT / REFERENTIE / VERLATEN / LET


21

In JavaScript zijn er twee soorten scope:

  • Lokale scope
  • Global Scope

De functie Hieronder heeft een lokale bereikvariabele carName. En deze variabele is niet toegankelijk van buiten de functie.

function myFunction() {
    var carName = "Volvo";
    alert(carName);
    // code here can use carName
}

De onderstaande klasse heeft een globale bereikvariabele carName. En deze variabele is overal in de klas toegankelijk.

class {
    var carName = " Volvo";
    // code here can use carName
    function myFunction() {
        alert(carName);
        // code here can use carName 
    }
}

Antwoord 22

Ik vind het geaccepteerde antwoord erg leuk, maar ik wil dit toevoegen:

Scope verzamelt en onderhoudt een opzoeklijst van alle gedeclareerde identifiers (variabelen) en handhaaft een strikte set regels met betrekking tot hoe deze toegankelijk zijn voor code die momenteel wordt uitgevoerd.

Reikwijdte is een set regels voor het opzoeken van variabelen op basis van hun identificatienaam.

  • Als een variabele niet in het directe bereik kan worden gevonden, raadpleegt Engine het volgende buitenste bevattende bereik en gaat door totdat het is gevonden of totdat het buitenste (ook wel globale) bereik is bereikt.
  • Is de set regels die bepaalt waar en hoe een variabele (identifier) kan worden opgezocht. Deze look-up kan zijn bedoeld om toe te wijzen aan de variabele, wat een LHS-referentie (links) is, of om de waarde ervan op te halen, wat een RHS-referentie (rechterkant) is .
  • LHS-referenties zijn het resultaat van toewijzingsbewerkingen. Scope-gerelateerde toewijzingen kunnen plaatsvinden met de = operator of door argumenten door te geven aan (toewijzen aan) functieparameters.
  • De JavaScript-engine compileert eerst de code voordat het wordt uitgevoerd, en daarbij splitst het uitspraken als VAR A = 2; in twee afzonderlijke stappen: 1e. Ten eerste, var A om het in die reikwijdte te verklaren. Dit wordt aan het begin uitgevoerd, vóór de uitvoering van de code. 2e. Later, A = 2 om de variabele (LHS-referentie) op te zoeken en toe te wijzen als deze wordt gevonden.
  • Beide LHS- en RHS-referentie-look-ups beginnen bij de momenteel uitvoerende reikwijdte, en indien nodig (dat wil zeggen, ze vinden niet wat ze daar zoeken), ze werken hun weg naar de geneste scope, één Reikwijdte (vloer) per keer, op zoek naar de identifier, totdat ze naar de wereldwijde (bovenste verdieping) en stoppen, en het vinden, of niet. Onvervulde RHS-referenties resulteren in referenceError die wordt gegooid. Unfuled LHS-referenties resulteren in een automatische, impliciet gemaakte globaal van die naam (indien niet in strikte modus) of een referenterror (indien in strikte modus).
  • Scope bestaat uit een reeks “bubbels” die elk optreden als een container of emmer, waarin identifiers (variabelen, functies) worden verklaard. Deze bubbels nest ze netjes in elkaar en dit nestelen wordt gedefinieerd bij auteurstijd.

Antwoord 23

In EcmaScript5 zijn er hoofdzakelijk twee scopes, local scopeen global scopemaar in EcmaScript6 hebben we voornamelijk drie scopes, lokale scope, globale scope en een nieuwe scope genaamd bereik blokkeren.

Voorbeeld van blokkering is:-

for ( let i = 0; i < 10; i++)
{
 statement1...
statement2...// inside this scope we can access the value of i, if we want to access the value of i outside for loop it will give undefined.
}

Antwoord 24

ECMAScript 6 introduceerde de sleutelwoorden let en const. Deze trefwoorden kunnen worden gebruikt in plaats van het trefwoord var. In tegenstelling tot het var-sleutelwoord ondersteunen de let- en const-sleutelwoorden de declaratie van lokaal bereik binnen blokinstructies.

var x = 10
let y = 10
const z = 10
{
  x = 20
  let y = 20
  const z = 20
  {
    x = 30
    // x is in the global scope because of the 'var' keyword
    let y = 30
    // y is in the local scope because of the 'let' keyword
    const z = 30
    // z is in the local scope because of the 'const' keyword
    console.log(x) // 30
    console.log(y) // 30
    console.log(z) // 30
  }
  console.log(x) // 30
  console.log(y) // 20
  console.log(z) // 20
}
console.log(x) // 30
console.log(y) // 10
console.log(z) // 10

Antwoord 25

(function foo() { console.log(foo) })();
console.log(typeof foo); // undefined, because `foo` is scoped to its own expression
//but, like this
(function foo() {
    console.log('1:', foo) // function foo
    foo = 100
    console.log('2:', foo) // function foo, is not 100, why?
})()

Antwoord 26

Er zijn twee soorten bereiken in JavaScript.

  1. Global scope: variabele die in global scope wordt aangekondigd, kan overal in het programma heel soepel worden gebruikt. Bijvoorbeeld:

    var carName = " BMW";
    // code here can use carName
    function myFunction() {
         // code here can use carName 
    }
    
  2. Functioneel bereik of lokaal bereik: variabele gedeclareerd in dit bereik kan alleen in zijn eigen functie worden gebruikt. Bijvoorbeeld:

    // code here can not use carName
    function myFunction() {
       var carName = "BMW";
       // code here can use carName
    }
    

Other episodes