Javascript-bruksdirektivet støttes av alle nettlesere. Hva gjør "bruk streng" i JavaScript, og hva er årsakene til det? streng modus i funksjoner

(videre i artikkelen Strict Mode). Strict Mode legger et lag med begrensninger på JavaScript som holder deg unna farlige deler av språket (de delene som historisk eksisterer, men som det er bedre å ikke være der) og lar deg redusere sannsynligheten for feil.

Mens jeg leste denne artikkelen, skrev jeg 38 tester som dekker alle strenge modus-reglene som er deklarert i ES5-spesifikasjonen. Du kan se hvor godt nettleseren din støtter disse reglene.

Koden for hver test er gitt på slutten av artikkelen for å hjelpe deg med å forstå spesifikasjonen bedre. Du kan også kjøre testen manuelt ved å kopiere koden til konsollen. All kildekode er i mitt depot.

Firefox 4 støtter allerede Strict Mode fullt ut, og Chrome 11 nesten fullstendig. Strict Mode er rett rundt hjørnet - la oss utforske det mer detaljert!

Hvordan aktiverer jeg streng modus? Hvis du legger til "bruk streng" i begynnelsen av JavaScript-koden din, vil streng modus bli brukt på hele koden:
"bruk streng"; 012; //Octal literal er ikke tillatt. Vil kaste et SyntaxError-unntak i streng modus
Alternativt kan du aktivere streng modus bare i en egen funksjon ved å legge til "bruk streng" i begynnelsen av funksjonsteksten:
012; //Ingen feil (Streng modus er ikke aktivert globalt) function foo() ( "bruk streng"; x=3; //Streng modus vil gi et unntak - det er forbudt å implisitt lage globale variabler ) foo(); //ReferenceError (Strict Mode aktivert for funksjon) Arver interne funksjoner Strict Mode fra eksterne funksjoner? En intern funksjon som er deklarert inne i en ekstern funksjon der Strict Mode er aktivert, vil også ha Strict Mode:
var wrapper = function(fn) ( "bruk streng"; var deleteNonConfigurable = function () ( var obj = (); Object.defineProperty(obj, "name", (konfigurerbar: false )); slett obj.name; // Vil kaste et TypeError-unntak i streng modus ) return deleteNonConfigurable; ) wrapper())(; //TypeError (streng modus aktivert)
Det er viktig å huske at Strict Mode ikke gjelder for "ikke-strenge" funksjoner som utføres i en streng funksjon (enten sendes de til funksjonen som argumenter eller utføres ved bruk av call eller application):
var test = function(fn) ( "bruk streng"; fn(); ) var deleteNonConfigurable = funksjon () ( var obj = (); Object.defineProperty(obj, "navn", (konfigurerbar: usann )); slett obj .name; // Kaster et TypeError-unntak i streng modus ) test(deleteNonConfigurable); //ingen feil (Streng modus ble ikke brukt) Hvorfor kan jeg ikke aktivere streng modus i nettleserkonsollen? Når du kjører kode i firebug-konsollen eller andre konsoller, har bruk av "bruk streng" utenfor en funksjon ingen effekt. Dette er fordi de fleste konsoller pakker inn koden din i en eval, så "bruk streng" er ikke det første uttrykket. Du kan komme rundt dette ved å pakke inn koden din i en IIFE-lukking, som vi setter "bruk streng" i begynnelsen av ( men da jeg testet denne metoden for å aktivere Strict Mode, innså jeg at dette er ganske upraktisk, spesielt hvis du jobber i webkit-utviklerverktøykonsollen - det er bedre å teste koden din på siden):
(function() ("bruk streng"; var a; var b; funksjonslinje() ( x = 5; //Streng modus vil gi et unntak for forsøk på å lage en global variabel) bar(); // ReferenceError (Strict Modus aktivert) ) )(); Hva skjer hvis nettleseren min ikke støtter streng modus? Ingenting. "bruk streng"-direktivet er et regulært strenguttrykk som vil bli ignorert av alle JavaScript-motorer som ikke støtter streng modus. Dette lar deg trygt bruke streng modus-syntaks i alle nettlesere uten bekymringer mens nettlesere som støtter streng modus vil bruke det. Hvilke regler er inkludert i streng modus? Reglene er definert i Strict Mode-spesifikasjonen og inkluderer begrensninger under "kompilering" og tolkning (skriptutførelse). Dette er en innledende oversikt (jeg har beskrevet hver regel med eksempler i følgende avsnitt): ecma262-5.com/ELS5_HTML.htm#Annex_C Syntaksfeil I de fleste tilfeller forhindrer Strict Mode kjøring av mistenkelig eller ulovlig kode under oppstartsprosessen . Oktale tall, dupliserte variabelnavn, feil bruk av delete, og forsøk på å gjøre noe med eval og arguments nøkkelordet, bruk med vil resultere i en SyntaxError Ordet dette I streng modus vil dette objektet ikke bli justert. Dette er kanskje den mest interessante delen av Strict Mode og den vanskeligste (sjokkerende) for utviklere. Alle vet at hvis det første argumentet å kalle eller bruke er null eller udefinert, så vil denne verdien av funksjonen som utføres bli konvertert til et globalt objekt (for nettlesere er dette vindu). Direkte opprettelse av globale variabler Ikke alle vil være enige med dette, men indirekte å skape et globalt objekt er nesten alltid feil. I streng modus vil du få et rødt kort - ReferenceError.arguments.caller og arguments.callee Disse "nyttige egenskapene" (fra forfatteren har aldri brukt dem) er forbudt i streng modus. Hvis du bruker dem i koden din, vil Strict Mode gi et unntak Erklære et eksisterende objektnavn Når du lager et objekt med to identiske nøkler, vil Strict Mode gi et TypeError-unntak Tester Her er kilden til mine Strict Mode-tester. Hver testsuite har en kommentar som refererer til den delen av ECMAScript-spesifikasjonen som den tester. Denne versjonen kan kjøres i "konsollmodus". De. du kan kopiere testen, lime den inn i konsollen og kjøre uten endringer. Jeg brukte den samme koden, kjører i "HTML"-modus, for å lage testsiden som jeg presenterte for deg i begynnelsen av artikkelen. Denne kilden med flere objekter er i mitt github-lager. Jeg er sikker på at det er et par feil der inne - send gjerne inn feil!

Fra oversetteren: det var et stort stykke kode i artikkelen, jeg lastet det opp til pastebin

Konklusjon Å forby bruken av visse språkfunksjoner for å forbedre kode er et kontroversielt spørsmål, la oss legge disse debattene til side. Til Strict Modes forsvar vil jeg si at det er et flott kompromiss mellom å gjøre totale endringer (som vil bryte bakoverkompatibiliteten) og å ikke gjøre noe (som vil rote språket og lære utviklere dårlige ting). ECMA-262 5. utgave: The Strict Mode of ECMAScript
Asen Bozhilov: Strenge tester
ECMAScript 5-kompatibilitetstabell, del dedikert til streng modus. Dette er en utmerket kilde, en del av en stor kompatibilitetstabell utviklet av Juriy Zaytsev aka "kangax")

Fra oversetteren. Strict Mode støttes av nesten halvparten av alle nettlesere; i tillegg til sine utmerkede begrensninger og immunitet mot vanlige feil, gir Strict Mode andre fordeler (artikkel av mraleph). Snart vil det bli dårlig å ikke bruke Strict Mode (lik requestAnimationFrame vs setTimeout). Nå er det på tide å begynne å eksperimentere!

(videre i artikkelen Strict Mode). Strict Mode legger et lag med begrensninger på JavaScript som holder deg unna farlige deler av språket (de delene som historisk eksisterer, men som det er bedre å ikke være der) og lar deg redusere sannsynligheten for feil.

Mens jeg leste denne artikkelen, skrev jeg 38 tester som dekker alle strenge modus-reglene som er deklarert i ES5-spesifikasjonen. Du kan se hvor godt nettleseren din støtter disse reglene.

Koden for hver test er gitt på slutten av artikkelen for å hjelpe deg med å forstå spesifikasjonen bedre. Du kan også kjøre testen manuelt ved å kopiere koden til konsollen. All kildekode er i mitt depot.

Firefox 4 støtter allerede Strict Mode fullt ut, og Chrome 11 nesten fullstendig. Strict Mode er rett rundt hjørnet - la oss utforske det mer detaljert!

Hvordan aktiverer jeg streng modus? Hvis du legger til "bruk streng" i begynnelsen av JavaScript-koden din, vil streng modus bli brukt på hele koden:
"bruk streng"; 012; //Octal literal er ikke tillatt. Vil kaste et SyntaxError-unntak i streng modus
Alternativt kan du aktivere streng modus bare i en egen funksjon ved å legge til "bruk streng" i begynnelsen av funksjonsteksten:
012; //Ingen feil (Streng modus er ikke aktivert globalt) function foo() ( "bruk streng"; x=3; //Streng modus vil gi et unntak - det er forbudt å implisitt lage globale variabler ) foo(); //ReferenceError (Strict Mode aktivert for funksjon) Arver interne funksjoner Strict Mode fra eksterne funksjoner? En intern funksjon som er deklarert inne i en ekstern funksjon der Strict Mode er aktivert, vil også ha Strict Mode:
var wrapper = function(fn) ( "bruk streng"; var deleteNonConfigurable = function () ( var obj = (); Object.defineProperty(obj, "name", (konfigurerbar: false )); slett obj.name; // Vil kaste et TypeError-unntak i streng modus ) return deleteNonConfigurable; ) wrapper())(; //TypeError (streng modus aktivert)
Det er viktig å huske at Strict Mode ikke gjelder for "ikke-strenge" funksjoner som utføres i en streng funksjon (enten sendes de til funksjonen som argumenter eller utføres ved bruk av call eller application):
var test = function(fn) ( "bruk streng"; fn(); ) var deleteNonConfigurable = funksjon () ( var obj = (); Object.defineProperty(obj, "navn", (konfigurerbar: usann )); slett obj .name; // Kaster et TypeError-unntak i streng modus ) test(deleteNonConfigurable); //ingen feil (Streng modus ble ikke brukt) Hvorfor kan jeg ikke aktivere streng modus i nettleserkonsollen? Når du kjører kode i firebug-konsollen eller andre konsoller, har bruk av "bruk streng" utenfor en funksjon ingen effekt. Dette er fordi de fleste konsoller pakker inn koden din i en eval, så "bruk streng" er ikke det første uttrykket. Du kan komme rundt dette ved å pakke inn koden din i en IIFE-lukking, som vi setter "bruk streng" i begynnelsen av ( men da jeg testet denne metoden for å aktivere Strict Mode, innså jeg at dette er ganske upraktisk, spesielt hvis du jobber i webkit-utviklerverktøykonsollen - det er bedre å teste koden din på siden):
(function() ("bruk streng"; var a; var b; funksjonslinje() ( x = 5; //Streng modus vil gi et unntak for forsøk på å lage en global variabel) bar(); // ReferenceError (Strict Modus aktivert) ) )(); Hva skjer hvis nettleseren min ikke støtter streng modus? Ingenting. "bruk streng"-direktivet er et regulært strenguttrykk som vil bli ignorert av alle JavaScript-motorer som ikke støtter streng modus. Dette lar deg trygt bruke streng modus-syntaks i alle nettlesere uten bekymringer mens nettlesere som støtter streng modus vil bruke det. Hvilke regler er inkludert i streng modus? Reglene er definert i Strict Mode-spesifikasjonen og inkluderer begrensninger under "kompilering" og tolkning (skriptutførelse). Dette er en innledende oversikt (jeg har beskrevet hver regel med eksempler i følgende avsnitt): ecma262-5.com/ELS5_HTML.htm#Annex_C Syntaksfeil I de fleste tilfeller forhindrer Strict Mode kjøring av mistenkelig eller ulovlig kode under oppstartsprosessen . Oktale tall, dupliserte variabelnavn, feil bruk av delete, og forsøk på å gjøre noe med eval og arguments nøkkelordet, bruk med vil resultere i en SyntaxError Ordet dette I streng modus vil dette objektet ikke bli justert. Dette er kanskje den mest interessante delen av Strict Mode og den vanskeligste (sjokkerende) for utviklere. Alle vet at hvis det første argumentet å kalle eller bruke er null eller udefinert, så vil denne verdien av funksjonen som utføres bli konvertert til et globalt objekt (for nettlesere er dette vindu). Direkte opprettelse av globale variabler Ikke alle vil være enige med dette, men indirekte å skape et globalt objekt er nesten alltid feil. I streng modus vil du få et rødt kort - ReferenceError.arguments.caller og arguments.callee Disse "nyttige egenskapene" (fra forfatteren har aldri brukt dem) er forbudt i streng modus. Hvis du bruker dem i koden din, vil Strict Mode gi et unntak Erklære et eksisterende objektnavn Når du lager et objekt med to identiske nøkler, vil Strict Mode gi et TypeError-unntak Tester Her er kilden til mine Strict Mode-tester. Hver testsuite har en kommentar som refererer til den delen av ECMAScript-spesifikasjonen som den tester. Denne versjonen kan kjøres i "konsollmodus". De. du kan kopiere testen, lime den inn i konsollen og kjøre uten endringer. Jeg brukte den samme koden, kjører i "HTML"-modus, for å lage testsiden som jeg presenterte for deg i begynnelsen av artikkelen. Denne kilden med flere objekter er i mitt github-lager. Jeg er sikker på at det er et par feil der inne - send gjerne inn feil!

Fra oversetteren: det var et stort stykke kode i artikkelen, jeg lastet det opp til pastebin

Konklusjon Å forby bruken av visse språkfunksjoner for å forbedre kode er et kontroversielt spørsmål, la oss legge disse debattene til side. Til Strict Modes forsvar vil jeg si at det er et flott kompromiss mellom å gjøre totale endringer (som vil bryte bakoverkompatibiliteten) og å ikke gjøre noe (som vil rote språket og lære utviklere dårlige ting). ECMA-262 5. utgave: The Strict Mode of ECMAScript
Asen Bozhilov: Strenge tester
ECMAScript 5-kompatibilitetstabell, del dedikert til streng modus. Dette er en utmerket kilde, en del av en stor kompatibilitetstabell utviklet av Juriy Zaytsev aka "kangax")

Fra oversetteren. Strict Mode støttes av nesten halvparten av alle nettlesere; i tillegg til sine utmerkede begrensninger og immunitet mot vanlige feil, gir Strict Mode andre fordeler (artikkel). Snart vil det å ikke bruke streng modus bli dårlig oppførsel (lignende). Nå er det på tide å begynne å eksperimentere!

I denne artikkelen skal vi se på en av de viktigste funksjonalitetene til JavaScript, kalt «strict mode».

Vi kjører vanligvis Javascript-kode i normal modus, som tillater mange ting som faktisk er feil og utrygge. Men når vi bruker streng modus, kjøres Javascript-koden uten å ignorere ugyldig syntaks, og gjør derfor koden sikrere.

Bruker "streng modus"

For å begynne å kjøre kode i streng modus, må vi bruke "bruk streng"-direktivet. Det er bare et uttrykk. Dette direktivet støttes i JavaScript 1.8.5 (ECMAScript 5) eller høyere.

Bruker "bruk strengt"-direktivet

Det er to måter å bruke "bruk strengt"-direktivet på. Vi kan bruke den enten inne i en funksjonserklæring helt i begynnelsen eller i en global erklæring i begynnelsen av filen.
Når vi bruker "streng modus" som et globalt direktiv, kjører all javascript-kode på siden i streng modus. For eksempel:

Funksjon print(verdi) (
console.log(verdi);
}

Når vi bruker "bruk streng" i en funksjonsdeklarasjon, blir all kode i funksjonen utført i streng modus. All annen kode utenfor funksjonen kjøres normalt.
For eksempel:

Funksjon print(verdi) (
"bruk strengt"
console.log(verdi);
}

Funksjon print_twice(value) (
console.log(verdi);
console.log(verdi);
}

Hva vi ikke kan gjøre i streng modus: Bruke en ikke-deklarert variabel

I streng modus kan vi ikke bruke en ikke-deklarert variabel.

"bruk streng"
a = 12; // kaster et unntak i streng modus. I ikke-streng modus opprettes en ny egenskap for vindusobjektet.

slett operatør

Slett-operatoren brukes til å fjerne egendefinerte egenskaper fra et objekt og matriseelementer. Hvis vi prøver å fjerne noe annet enn brukerdefinerte objektegenskaper eller array-elementer, får vi et unntak.

Var a = 78;
window.b = 34;

Funksjon print()()
window.c = funksjon () ()

Slett en; // kaster et unntak i streng modus. I standardmodus returnerer den falsk og programmet fortsetter å kjøre

Slett window.a; // kaster et unntak i streng modus. I ikke-standard modus returnerer den falsk og programmet fortsetter.

Slett window.b; // I begge modusene er b-egenskapen fjernet
.
slett Math.PI; // I ikke-streng modus returnerer den falsk fordi PI er forhåndsdefinert. I streng modus - et unntak.

Slett Object.prototype; // sletting av en innebygd egenskap i ikke-streng modus returnerer false. Men i streng modus blir et unntak kastet.

Bare husk at uansett hvor sletting returnerer falsk i ikke-streng modus, gir det et unntak i streng modus.

Flere eiendomserklæringer

I streng modus kan du ikke deklarere de samme egenskapene på et objekt mer enn én gang. Ellers vil det gi et unntak.

Var mittObjekt = (egenskap1: 1, egenskap2: 2, egenskap1: 1); // kaster et unntak.

Det er alt, og i den neste artikkelen vil vi fortsette å studere JavaScript-direktivet "bruk strengt".

Strenge modus er en funksjon i ECMAScript 5-spesifikasjonen som lar deg bytte til en spesiell, "begrenset" versjon av JavaScript. Strenge modus pålegger en rekke begrensninger på språkkonstruksjoner, og eliminerer dermed noen fallgruver og forhindrer feil. Strengt modus gir også flere unntak, vanligvis med en mer detaljert beskrivelse av feilen.

Aktivering av streng modus gjøres ved å bruke følgende konstruksjon:

Strengt modus gjelder for hele skriptet eller individuelle funksjoner, men kan ikke aktiveres individuelt for en blokk. Et eksempel på aktivering av streng modus for en funksjon:

Merk at ingen ny syntaks er lagt til for å aktivere streng modus. Strengkonstanten 'bruk streng' vil bli ignorert av eldre nettlesere som ikke støtter streng modus. På denne måten kan du bruke streng modus uten å bekymre deg for at det gir en feil i eldre nettlesere.

Aktivering av streng modus bare for en funksjon lar deg skrive dine egne biblioteker i streng modus, mens resten av koden ikke vil bli påvirket av dette direktivet.

Når du bruker bruk streng for hele skriptet, må du være forsiktig med å slå sammen filer. Når du kombinerer et skript i streng modus med et skript i ikke-streng modus, vil det resulterende skriptet kjøres i streng modus. Dette kan forårsake noen feil som ikke var ment da det andre skriptet ble skrevet. Derfor anbefales det å pakke inn koden inne i hvert skript med en anonym funksjon og aktivere streng modus for den.

Endringer til streng modus

JavaScript ble designet for å være et enkelt språk for begynnende utviklere. Derfor er det en rekke subtile punkter i den som ikke regnes som feil, men som kan gi opphav til dem eller skape problemer i fremtiden. I streng modus regnes slike subtile poeng som feil og unntak blir kastet.

For eksempel, i streng modus er det umulig å jobbe med ikke-oppgitte variabler. Mens i ikke-streng modus, vil tildeling av en ikke-deklarert variabel ganske enkelt legge til en egenskap med det navnet til det globale objektet, i streng modus vil det forårsake en feil:

I streng modus blir unntak kastet i visse situasjoner der ingenting ville skje i normal modus. For eksempel gjør det ingenting å tildele NaN i normal modus, tildelingen skjer ikke, og utvikleren mottar ingen informasjon om det. I streng modus gir en slik oppgave et unntak. På samme måte vil enhver annen oppgave som ikke utføres i stillhet i normal modus gi et unntak i streng modus.

Strengt modus krever at alle egenskapene til et objekt er unike. I normal modus kan du definere egenskaper for et objekt med samme navn, og egenskapsverdien vil bli hentet fra sistnevnte. I streng modus vil en slik kode også gi et unntak.

På samme måte må parameterne som sendes til funksjonen også være unike:

Strenge modus forbyr bruk av with() ()-konstruksjonen. Problemet er at en variabel inne i denne blokken kan referere til enten en egenskap til objektet som sendes til med, en lokal variabel eller en egenskap til et globalt objekt.

En annen forskjell mellom streng modus og ikke-streng modus er at i streng modus, når verdien av dette overføres til en funksjon ved å bruke call, apply eller bind, er denne verdien ikke pakket inn i et objekt. I ikke-streng modus, hvis en streng, tall eller boolsk verdi sendes som denne, blir den pakket inn i den tilsvarende strengen, tall eller boolsk objekt. Hvis null eller udefinert sendes, blir det globale objektet dette objektet. I streng modus overføres denne verdien som den er:

Konklusjon

Strenge modus er et slags kompromiss mellom å fullstendig nekte å støtte noen språkfunksjoner og å støtte dem fullt ut. I streng modus begrenser du deg bevisst fra mulige feil forbundet med uoppmerksomhet, uforsiktig bruk av visse strukturer, etc.

Logiske operatører som oftest, brukes med den boolske datatypen og returnerer en boolsk verdi (true eller usant).

Vanligvis ... kalles disse operatørene faktisk "boolske" operatører, men i JavaScript kan de operere på verdier av enhver type og også returnere verdier av enhver type.

&& - logisk OG

Med logisk Og ved første øyekast er alt enkelt, hvis begge operandene er sanne, så er uttrykket sant:

Dette eksemplet kan være litt mer komplisert og bruke operander for å skrive sammenligningsuttrykk.

Men i virkeligheten er ikke alt så enkelt. I dette eksemplet brukte vi sammenligningsoperatorer, de returnerer de boolske verdiene sant / usant. Men operandene til logisk OG kan være uttrykk med aritmetiske operatorer.

La oss endre eksempelet:

I dette eksemplet vil &&-operatøren returnere 11. Faktum er at &&-operatøren faktisk returnerer den siste operanden hvis alle operandene er sanne.

Hvis minst én av operandene er usann, vil && returnere den første operanden med verdien false.

I dette eksemplet vil &&-operatoren returnere tallet 0. Du kan, for en dypere forståelse, komplisere eksempelet.

Hva er usann i JavaScript

Nå er det en god grunn til å gjenta at det er en løgn i JavaScript.

  • Tall 0 (null).
  • Tom linje "".
  • boolsk verdi usann :)
  • Verdien er null.
  • Verdien er udefinert.
  • Verdien er NaN (ikke et tall).

Alt annet i en logisk sammenheng vil være sant.

|| - logisk ELLER

Den logiske ELLER-operatoren returnerer den første verdien sann. Og hvis det ikke er noen sanne verdier, så er den siste falsk.

Boolske uttrykk evalueres fra venstre til høyre. Så snart OR-operatøren oppdager verdien sann, vil den returnere den, og det vil ikke være flere beregninger. Hvis den ikke støter på noen sanne verdier, vil den returnere den siste verdien, og den vil definitivt være usann. Vi ser at OR beregner nøyaktig så mange verdier som trengs.

! La oss lære JavaScript "bruk strengt". Del 1

- logisk IKKE

Logical NOT er en unær operatør. Den tar en operand og reverserer dens sanne/falske verdi.

Det blir også åpenbart at ved å bruke en dobbel logisk NOT kan vi konvertere en bokstavelig til en boolsk type.

Kort syklus av beregninger Operatør || (ELLER)

Så boolske uttrykk evalueres fra venstre til høyre. For eksempel, når OR-operatøren finner verdien sann, vil den returnere den, og det vil ikke være flere beregninger. Denne funksjonen kan brukes til å finne det første sanne uttrykket i en liste.

Resultatvariabelen vil være lik "Hallo!". Postfix-inkrementet myVar++ vil bli utført etter at uttrykket er evaluert, men prefikset-inkrementet ++myVar vil ikke bli utført, siden den tidligere operatoren || vil oppdage sannheten.

Operatør && (OG)

Beregner fra venstre til høyre, hvis argumentet er usant, returnerer &&-operatoren det og avslutter beregningen. Ellers beregner den videre, hvis false ikke er på listen, returnerer den det siste høyre argumentet, som vil være sant.

Her er et eksempel:

Beregningene vil stoppe ved myStr-variabelen, og det er verdien "" som vil bli tilordnet resultatvariabelen.

&& i stedet for if

I enkle tilfeller kan du bruke &&-operatoren i stedet for en if-setning:

I dette eksemplet vil den høyre operanden kun utføres hvis den venstre operanden er boolsk type true.

Den moderne modusen, "bruk streng" var (C# Reference)var (C# Reference)

Fra og med Visual C# 3.0 kan variabler som er deklarert ved metodeomfang ha en implisitt "type" . Implisitt skrevne lokale variabler er sterkt skrevet, da En implisitt skrevet lokal variabel er sterkt skrevet akkurat som om du hadde deklarert typen selv, men kompilatoren bestemmer typen. Følgende to erklæringer av er funksjonelt likeverdige:

For mer informasjon, se Implisitt innskrevne lokale variabler og typerelasjoner i LINQ-spørringsoperasjoner.

Eksempel

Følgende eksempel viser to spørringsuttrykk. I det første uttrykket er bruk av tillatt, men er ikke nødvendig fordi søkeresultattypen kan spesifiseres eksplisitt etter behov, fordi typen av spørringsresultatet kan angis eksplisitt som en . Imidlertid , i det andre uttrykket, lar resultatet være en samling av anonyme typer, og navnet på den typen er ikke tilgjengelig bortsett fra kompilatoren selv. Bruk av eliminerer kravet om å opprette en ny klasse for resultatet. Merk at i Note at i eksempel #2 må iterasjonsvariabelen også være implisitt skrevet.

Se også

C#C# referanse
C#C# programmeringsveiledning
Implisitt innskrevne lokale variabler

Finn ut hvordan du fikser JavaScript-feil ved å bruke nettleserkonsollen og mer. Vi vil lære av eksempler hvordan vi skal håndtere js-feil og andre problemer. Vi vil også dele vår praksis for å håndtere feil i kommentarene.

Hva skal vi lære i dag?

Visualisere feil i JavaScript

Eksempler på å fikse feil ved hjelp av konsollen

Hvordan fikse en feil uten konsoll

Møt konsollen!

Etter å ha snakket med utviklervennene mine, ble jeg overrasket over at de aldri bruker nettleserkonsoller for å håndtere feil i koden.

Vel, hvis du ikke allerede bruker konsollen til å identifisere og fikse feil, anbefaler jeg deg å prøve det akkurat nå.

Visualisering ved retting av feil

Når det gjelder PHP, er alt enklere. Feilen stopper skriptet fra å kjøre og linjenummeret og skriptfilen vises. Men med JS er alt annerledes, selv om det alltid er en vei ut. Kort sagt, du kan gjøre en utmerket feilkontroll av javascript-kode når du laster inn en side.

Nettleserkonsollen er et objekt som kan brukes til å vise feilinformasjon mens en side lastes inn. For eksempel: du kan komme til et hvilket som helst DOM-element, for eksempel et bilde som ikke har riktig URL. For å gjøre dette må du peke på elementet (bilde) og trykke på høyre museknapp. Finn "Inspiser element" eller noe lignende. I Opera ser det slik ut:

Her er vi i konsollen. Nesten alt som gjenstår er å velge "konsoll"-fanen.

Konsollen, i motsetning til "kildekoden", er i stand til å se gjeldende endringer på siden som er forårsaket av JavaScript-kode.

Og her er tilgang til konsollen i Chrome-nettleseren:

Enkle eksempler på feilsøking

Konsollen støtter mange alternativer, men du kan klare deg med 3-4, dette er nok til å identifisere og korrigere feilen ytterligere. Fra min egen erfaring er log()-funksjonen den mest praktiske. Den sender ut nye meldinger, DOM-elementer, variabler til konsollen der vi kan se dem. Eksemplene nedenfor viser applikasjonene til funksjonene jeg bruker.

I dette skriptet viser konsollen forskjellige resultater avhengig av verdien av variabelen full_name (tom eller ikke).

if (full_name != "")( console.log('Navnet \"' + fullt_navn + '\" ble angitt'); )else( console.error('Intet navn ble angitt'); )

For en jQuery-klikkhendelse vil konsollen skrive ut informasjon om elementet som klikkes (spores):

Konsollen er mer enn bare å sende ut meldinger; den kan også godta kommandoer. Skriv for eksempel "dokument" og trykk Enter for å få informasjon om siden.

Hvordan fikser jeg feilen uten konsollen?

Hvis du synes det er vanskelig å forstå funksjonene til konsollen, eller nettleseren din ikke støtter denne funksjonen. Jeg anbefaler deg å bruke en enkel og velprøvd metode for å fikse feil i javascript-koden. Mens du koder, kan du ganske enkelt sette inn utdataene fra meldingen ();

Eksempler på å identifisere feil ved hjelp av varsling

Dette eksemplet lar deg ganske enkelt vise verdien til en variabel:

var e = 123; varsling(e); // vil gi ut 123

Du kan også forstå hvor verdien er og hvor objektet er:

var e = document.getElementById(id_elementa); varsling(e); // viser en melding om at et objekt er valgt

En annen applikasjon er å finne ut hvilken kodelinje som forårsaket en feil. For å gjøre dette trenger du bare å sette inn meldinger som alert('Det er en feil her'); hver linje med kode. For eksempel:

alert('Hei'); var e = document.getElementByIds(‘id_elementa’); alert('Hei 2');

I dette tilfellet vil bare Hei-meldingen vises. For det er en feil på den andre linjen! Hvis det ikke er noen feil, vil 2 meldinger vises.

Streng modus i JavaScript

Metoden er dum, men den fungerer. Det viktigste er uten å bruke konsollen, jeg kopierte -> limte inn og bestemte hvor feilen var i koden. Hvis ikke nødvendig, kommenter det.

Hold siden ren!

Dette er de nødvendige verktøyene som jeg holder siden og javascript-koden ren med. Neste gang, mens du jobber med et javascript-prosjekt, anbefaler jeg deg å bruke konsollen eller bare vise varselmeldinger. Dette er veldig praktisk og lar deg rette feilen.

JavaScript - streng modus

Strengt regime

Noen ganger vil du se en ikke-standard standardmodus kalt "slurvete modus". Dette er ikke et offisielt begrep, men husk det i tilfelle.

(function() ("bruk streng"; false.true = ""; // TypeError (14).sailing = "home"; // TypeError "with".you = "langt borte"; // TypeError ))( );

Forenkling av bruken av variabler

Strengt modus gjør det enklere å matche variabelnavn til spesifikke variabeldefinisjoner i koden din. Mange kompilatoroptimalisatorer er avhengige av muligheten til å fortelle at en variabel X lagret i dette plassering: Dette er avgjørende for å optimalisere JavaScript-koden. JavaScript gjør noen ganger denne grunnleggende tilordningen av et navn til en variabeldefinisjon i kode som ikke kan gjøres før kjøring. Strengt modus fjerner de fleste tilfeller der dette skjer, slik at kompilatoren bedre kan optimalisere streng moduskode.

For det første er strenge regimer forbudt. Problemet er at et hvilket som helst navn inne i en blokk kan gjenspeile enten en egenskap til objektet som er sendt til den, eller en variabel i miljøet (eller til og med en global) under kjøring: det er ingen måte å vite dette på forhånd. Strengt modus kjøres med en syntaksfeil, så det er ingen mulighet for et navn i en som refererer til en ukjent plassering under kjøring:

"bruk streng"; var x = 17; med (obj) ( // !!! syntaksfeil // Hvis dette ikke var "t strict mode, ville dette vært var x, eller // ville det i stedet vært obj.x? Det er umulig generelt // å si uten å kjøre koden, så navnet kan ikke // optimaliseres. x; )

Det enkle alternativet med å tilordne et objekt til en kortnavnvariabel, og deretter få tilgang til den tilsvarende egenskapen for den variabelen, er klar til å erstatte med .

For det andre, . I normal kode introduserer eval("var x;") variabelen x i den omkringliggende funksjonen eller globale omfanget. Dette betyr at, generelt sett, i en funksjon som inneholder et kall til eval, må hvert ikke-argument eller lokale variabelnavn tilordnes en konkret definisjon ved kjøring (siden den evalen kan introdusere en ny variabel som vil skjule den ytre variabelen). I streng modus oppretter eval kun variabler for koden som evalueres, så eval kan ikke påvirke om et navn refererer til en ekstern variabel eller en lokal variabel:

Var x = 17; var evalX = eval(""bruk streng"; var x = 42; x;"); console.assert(x === 17); console.assert(evalX === 42);

Hvis evalfunksjonen kalles opp av et uttrykk av formen eval(...) i streng moduskode, vil koden bli evaluert som streng moduskode. Koden kan eksplisitt referere til streng modus, men det trenger den ikke.

Funksjon streng1(str) ( "bruk streng"; return eval(str); // str vil bli behandlet som streng moduskode ) funksjon streng2(f, str) ( "bruk streng"; return f(str); // ikke eval(...): str er streng hvis og bare // hvis den påkaller streng modus ) funksjon nonstrict(str) ( returner eval(str); // str er streng hvis og bare // hvis den påkaller streng modus ) strict1 (""Streng moduskode!""); strict1(""bruk streng"; "Streng moduskode!""); strict2(eval, ""Ikke-streng kode.""); strict2(eval, ""bruk streng"; "Streng moduskode!""); nonstrict(""Ikke-streng kode."); nonstrict(""bruk streng"; "Streng moduskode!"");

Navn i streng eval-kode oppfører seg dermed på samme måte som navn i streng modus, som ikke blir evaluert som et resultat av eval .

For det tredje forbyr det strenge regimet fjerning av enkle navn. slett navn i streng modus er en syntaksfeil:

"bruk streng"; var x; slett x; //!!! syntaksfeileval("var y; slett y;"); //!!! syntaksfeil

Forenkling av vurdering og argumenter

Strengt modus gjør argumenter og eval mindre rart magisk. Begge involverer en betydelig mengde magisk oppførsel i normal kode: eval for å legge til eller fjerne bindinger og endre bindingsverdier, og argumenter som bruker indekserte aliasingsegenskaper på argumentnavn. Strenge modus gjør store fremskritt for å behandle eval og argumenter som nøkkelord, selv om fullstendige rettelser ikke vises før en fremtidig utgivelse av ECMAScript.

For det første kan ikke navnene eval og argumenter assosieres eller tildeles i språksyntaksen. Alle disse forsøkene er syntaksfeil:

"bruk streng"; eval = 17; argumenter++; ++eval; var obj = ( sett p(argumenter) ( ) ); var eval; try ( ) catch (argumenter) ( ) funksjon x(eval) ( ) funksjonsargumenter() ( ) var y = funksjon eval() ( ); var f = new Function("argumenter", ""bruk streng"; return 17;");

For det andre støtter ikke streng moduskode egenskapene til argumentobjekter som er opprettet i den. I normal kode inne i en funksjon hvis første argument er arg , setter arg-parameteren også argumenter og omvendt (hvis ingen argumenter er oppgitt eller argumenter fjernes). arguments-objekter for strengmodusfunksjoner lagrer de originale argumentene når funksjonen kalles. arguments[i] holder ikke styr på verdien av det tilsvarende navngitte argumentet, og heller ikke et navngitt argument holder styr på verdien i de tilsvarende argumentene[i] .

Funksjon f(a) ( "bruk streng"; a = 42; return ; ) var par = f(17); console.assert(par === 42); console.assert(par === 17);

For det tredje støttes ikke lenger arguments.callee. I vanlige argumenter refererer callee til avslutningsfunksjonen. Denne brukssaken er svak: bare ring aktiveringsfunksjonen! I tillegg gjør arguments.callee optimaliseringer som innebygde funksjoner mye vanskeligere, siden det er nødvendig å gi en referanse til en ikke-innebygd funksjon hvis access.callee får tilgang til den. arguments.callee for strengmodusfunksjoner er en ubrukt egenskap som genereres når den settes eller hentes:

"bruk streng"; var f = function() ( returner arguments.callee; ); f(); // kaster en TypeError

"Beskyttelse" av JavaScript

Strengt modus gjør det lettere å skrive "sikker" JavaScript. Noen nettsteder gir nå brukere muligheten til å skrive JavaScript som skal drives av nettstedet på vegne av andre brukere. JavaScript i nettlesere kan få tilgang til brukerens personlige informasjon, så slik JavaScript må delvis konverteres før den kjøres for å sensurere tilgang til forbudt funksjonalitet. Fleksibiliteten til JavaScript gjør det umulig å gjøre dette uten mange kjøretidskontroller. Noen språkfunksjoner er så vanlige at det har en betydelig kostnad å utføre kjøretidskontroller. Noen få strenge modusinnstillinger, samt kravet om at brukerens JavaScript skal være streng moduskode og at det kalles på en bestemt måte, reduserer behovet for disse kjøretidssjekkene i stor grad.

For det første tvinges ikke en verdi som sendes som en funksjon til en funksjon i streng modus inn i et objekt (aka "i en boks"). For en normal funksjon er dette alltid et objekt: enten det medfølgende objektet hvis det kalles opp med en objektverdi; verdi, innrammet, hvis det kalles med en boolsk, streng eller tall dette ; eller et globalt objekt hvis det kalles med undefined eller null dette. (Bruk kall , bruk eller bind for å spesifisere et spesifikt dette .) Ikke bare er autoboksing for ytelse, men global objektkartlegging i nettlesere er en sikkerhetsrisiko fordi det globale objektet gir tilgang til funksjoner som "beskytter" JavaScript-miljøer bør begrense. Derfor, for en streng modusfunksjon, blir den spesifiserte denne ikke plassert i objektet i objektet, og hvis ikke spesifisert, vil dette være udefinert:

"bruk streng"; function fun() ( returner dette; ) console.assert(moro() === udefinert); console.assert(fun.call(2) === 2); console.assert(fun.apply(null) === null); console.assert(fun.call(udefinert) === udefinert); console.assert(fun.bind(true)() === sant);

Dette betyr blant annet at det ikke lenger er mulig for nettlesere å referere til et vindusobjekt via dette inne i en streng modus-funksjon.

For det andre, i streng modus er det ikke lenger mulig å "gå" JavaScript-glasset gjennom vanlige utvidelser i ECMAScript. I normal kode med disse utvidelsene, når en funksjon fun er midt i en fun.caller , er fun.caller funksjonen som sist ble kalt fun , og fun.arguments er argumentene for at call to fun . Begge utvidelsene er problematiske for "sikker" JavaScript fordi de lar "sikker" kode få tilgang til "privilegerte" funksjoner og deres (potensielt usikrede) argumenter. Hvis moro er i streng modus, som fun.caller og fun.arguments er ikke fun.caller fun.arguments-egenskaper som kastes når de stilles inn eller hentes:

Funksjon restricted() ( "bruk streng"; restricted.caller; // kaster en TypeError restricted.arguments; // kaster en TypeError ) funksjon privilegedInvoker() (retur restricted(); ) privilegedInvoker();

For det tredje gir argumenter for strengmodusfunksjoner ikke lenger tilgang til de tilsvarende funksjonskallvariablene. I noen eldre ECMAScript-implementeringer var arguments.caller et objekt hvis egenskaper ble modifisert av variabler i den funksjonen. Dette er en sikkerhetsrisiko fordi det bryter evnen til å skjule privilegerte verdier gjennom funksjonsabstraksjon; dette eliminerer også de fleste optimaliseringer. Av disse grunnene implementerer ikke nyere nettlesere det. Men på grunn av sin historiske funksjonalitet er arguments.caller for en streng modusfunksjon også en falsk egenskap som kastes når den angis eller hentes:

"bruk streng"; function fun(a, b) ( "bruk streng"; var v = 12; return arguments.caller; // kaster en TypeError ) fun(1, 2); // viser ikke v (eller a eller b)

Baner vei for fremtidige versjoner av ECMAScript

Fremtidige versjoner av ECMAScript vil sannsynligvis introdusere ny syntaks, og streng modus i ECMAScript 5 håndhever noen begrensninger for å lette overgangen. Det vil være lettere å gjøre noen endringer hvis grunnlaget for disse endringene er strengt forbudt.

For det første, i streng modus, blir en kort liste med identifikatorer reserverte nøkkelord. Disse ordene er implementer, interface, let, package, private, protected, public, static og yield. I streng modus kan du ikke navngi eller bruke variabler eller argumenter med disse navnene.

Funksjonspakke(beskyttet) ( // !!! "bruk streng"; var implementerer; // !!! grensesnitt: // !!! while (true) (break interface; // !!! ) function private( ) ( ) // !!! ) function fun(static) ( "bruk streng"; ) // !!!

To Mozilla-spesifikke forbehold: For det første, hvis koden din er 1.8 eller høyere (som i chrome-kode eller når du bruker rettighet) og er streng moduskode, ble la og la-funksjonene de har siden disse er nøkkelord først introdusert. Men streng moduskode på Internett, lastet eller ..., vil ikke kunne bruke let / yield som identifikatorer. For det andre, mens ES5 ubetinget reserverer ordene klasse , enum , eksport , utvider , import og super , før Firefox 5 Mozilla kun reserverer dem i streng modus.

For det andre, . I normal nettlesermodus er funksjonsutsagn tillatt "overalt". Dette er ikke en del av ES5 (eller til og med ES3)! Dette er en utvidelse med inkonsekvent semantikk på tvers av nettlesere. Merk at ES2015 tillater funksjonspåstander utenfor toppnivået.

"bruk streng"; if (true) (funksjon f() ( ) // !!! syntaksfeil f(); ) for (var i = 0; i< 5; i++) { function f2() { } // !!! syntax error f2(); } function baz() { // kosher function eit() { } // also kosher }

Dette forbudet er ikke streng modus fordi slike funksjonssetninger er en utvidelse av base ES5. Men dette er en anbefaling fra ECMAScript-komiteen, og nettlesere implementerer den.

Streng modus i nettlesere

Store nettlesere implementerer nå streng modus. Vær imidlertid ikke blindt avhengig av det, siden det fortsatt er mange nettleserversjoner som brukes i naturen som har delvis eller ingen støtte for streng modus (f.eks. Internet Explorer under versjon 10!). Strenge modus endrer semantikken.Å stole på disse endringene vil introdusere feil og feil i nettlesere som ikke implementerer streng modus. Vær forsiktig når du bruker streng modus, og bevar tilliten til streng modus med funksjonstester som kontrollerer at de riktige delene av streng modus brukes. Endelig, definitivt test koden din i nettlesere som gjør og ikke støtter streng modus. Hvis du bare tester i nettlesere som ikke støtter streng modus, vil du sannsynligvis få problemer med nettlesere som gjør det, og omvendt.