JS slēgšana. Apkopes JavaScript: praktisks piemērs, funkcijas un noteikumi

Sveiki visiem! Šajā rakstā mēs apskatīsim kas ir slēgšana JavaScript.

Tas ir diezgan vienkāršs temats, bet tas prasa izpratni. Pirmkārt, aplūkosim, kas notiek funkcijas iekšienē.

Funkciju sveiciens (nosaukums) (
// lexicalenvironment \u003d (nosaukums: "Nikolai", teksts: undefined)
var teksts \u003d "hello," + nosaukums;
// lexicalenvironment \u003d (nosaukums: "Nikolai", teksts: "Sveiki, Nikolai")
Brīdinājums (teksts);
}

Sveiciens ("Nikolai");

Kas notiek šeit un kas ir Lexicalenvironment? Apskatīsim to ārā.

Kad funkcija tiek saukta, tas rada objektu LexicalenvironmentKurā tiek reģistrēti visi vietējie mainīgie un funkcijas, kā arī atsauce uz ārējo darbības jomu (par to vēlāk). Mūsu gadījumā mums ir vietējais mainīgais nosaukums.kas nekavējoties ir vērtība (tad, ka mēs iet), un tas "Nikolai". Vienā no rakstiem, ko es jau rakstīju, es jums atgādinu, ka tulkošana zina visu par visiem mainīgajiem. Tas ir par to, ka pašā funkcijas sākumā jau ir mainīgs tekstu., tulks zina par to, bet, tā kā mēs vēl neesam sasnieguši šā mainīgā lieluma uzdevumu, tas ir vienāds ar nenoteikts.. Tagad mēs piešķiram mainīgu vērtību, un mūsu objektu Lexicalenvironment Izmaiņas. Viņa īpašums tekstu. Tas kļūst vienāds ar to, ka mēs reģistrējām ("Sveiki, Nikolajs" mūsu gadījumā). Pēc tam, kad funkcija ir izstrādāta, objekts Lexicalenvironment Iznīcināt. Ar turpmākiem zvaniem tas tiks izveidots vēlreiz utt.

Tagad mēs pārvēršam nākamo piemēru. Pastāstiet man, kas būs atvasināts šajā gadījumā?

Var b \u003d 2;
Funkcija x (a) (
brīdinājums (a + b);
}
x (1);

Domāja? Es domāju, ka lielākā daļa atbildēja, ka 3. numurs tiks parādīts, un šī ir pareizā atbilde, taču jūs varat pateikt, kā tulks uzzināja par mainīgo b.? Galu galā, tas nav ķermeņa funkcijā. Ja nē, sapratīsim.

Faktiski javaScript. Ir slēpts īpašums [] . Kad funkcija ir deklarēta, tā vienmēr ir deklarēta kaut kur. Šī funkcija var būt citā funkcijā, var būt globālā objektā utt. Mūsu gadījumā funkcija ir deklarēta globālajā objektā. logs.tāpēc īpašums x. [] \u003d logs.

Var b \u003d 2;
Funkcija x (a) (// x. [] \u003d Logs
// lexicalenvironment \u003d (A: 1) -\u003e logs
brīdinājums (a + b);
}
x (1);

Šim bultiņai ir objekts Lexicalenvironment - Šī ir atsauce uz ārējo darbības jomu, un šo saikni ir izveidota ar īpašumu. [] . Tātad objektā Lexicalenvironment Mums būs atsauce uz ārējo objektu. logs.. Kad tulks meklē mainīgo, tad viņš vispirms meklē to objektā Lexicalenvironmenttad, ja viņš neatrada mainīgo, tad tas izskatās saitē, nonāk ārējā darbības jomā un meklē to tur un līdz galam. Ja viņš nav atradis šo mainīgo jebkurā vietā, tas būs kļūda. Mūsu gadījumā mainīgais a. Tulks ņems no objekta Lexicalenvironmentun mainīgais b. No objekta logs.. Protams, ja mums ir vietējais mainīgais b. Ar kādu vērtību, tas tiks ierakstīts objektā Lexicalenvironment Un pēc tam tiks ņemti no turienes, nevis no redzamības ārējās jomas.

SVARĪGS! Atcerieties, ka īpašums [] To uzstāda vietā, kur funkcija tika pasludināta, un tas nav radījis, tāpēc zemāk esošais kodekss parāda numuru 3, un ne 5, kā daži varētu domāt.

B \u003d 2;
Funkcija x (a) (
brīdinājums (a + b);
}

Funkcija y () (
var b \u003d 4;
X (1);
}

Tas bija viss prelūds tikai, lai saprastu, kā tas viss darbojas, un tas bija vieglāk, lai jūs varētu saprast, kā slēgšanas darbu. Un tagad mēs tieši ieslēdzam raksta tēmu.

Kā jau teicu, objekts Lexicalenvironment Katru reizi tiek iznīcināts katru reizi pēc funkcijas izpildes un tiek izveidots vēlreiz, kad atkārtoti zvanāt. Tomēr, ko tad, ja mēs vēlamies saglabāt šos datus? Tiem. Mēs vēlamies, lai viss tiktu reģistrēts Lexicalenvironment Tagad ir saglabājies un tika izmantots šādām problēmām? Tas ir tas, ka tas ir tas, ka slēgšana.

Funkciju sveiciens (nosaukums) (
// lexicalenvironment \u003d (nosaukums: "Nikolai")
Atgriešanās funkcija () (// [] \u003d lexicalenvironment
Brīdinājums (nosaukums);
};
}

VAR FUNC \u003d sveiciens ("Nikolai");
sveiciens \u003d null;
Func ();

Redzēsim, ko mēs darījām. Vispirms mēs izveidojam funkciju sveiciens.kurā vārds ir pagājis. Funkcija izveido objektu LexicalenvironmentJa īpašums ir izveidots (mūsu vietējais mainīgais) nosaukums. Un viņai ir piešķirts vārds "Nikolai". Un tagad ir svarīgi: mēs atgriežam citu funkciju no funkcijas, kurā mēs iegūstam brīdinājums. mainīgs nosaukums.. Tālāk mēs piešķiram mainīgo func. Vērtība atgriezās no funkcijas sveiciens.Un šī vērtība ir mūsu funkcija, kas parāda nosaukumu. tagad mēs sveiciens. Mēs piešķiram nulle. Mēs vienkārši iznīcinām mūsu funkciju sveiciens.tomēr, zvanot func.Tad mēs redzēsim mainīgo vērtību nosaukums.("Nikolai") funkcijas sveiciens.. Kā ir iespējams jums pateikt? Un ļoti vienkārši. Lieta ir tāda, ka mūsu atgrieztajai funkcijai ir arī īpašums. [] kas attiecas uz redzamības ārējo jomu, un šī ārējā darbības joma mūsu gadījumā ir objekts Lexicalenvironment Mūsu funkcija sveiciens.. Tāpēc, neskatoties uz to, ka mēs izdzēšam mūsu funkciju sveiciens., objekts Lexicalenvironment Nav dzēsts un palika atmiņā, un tas paliks atmiņā, līdz tas ir vismaz viena saite. Mums ir šī saite - mūsu atgrieztā funkcija, kas izmanto mainīgo nosaukums. no šīs iekārtas Lexicalenvironment.

Tātad, tagad dodiet definīciju kas ir slēgšana.

Ķēde - Funkcija ar visiem pieejamajiem mainīgajiem lielumiem.

Nu, raksts izrādījās diezgan apjomīgs, bet tas ir tikai tāpēc, ka es mēģināju aprakstīt visu slēgšanas procesu. Lai konsolidētu, es vēlos, lai vienkāršs piemērs - skaitītājs, izmantojot tēmu tikko pētīta. Lūdzu, rīkojieties ar kodu un rakstiet komentāros, kā un kāpēc tas darbojas. Ja jūs kaut ko nesaprotat, jūs varat arī uzdot jautājumu. Paldies par uzmanību!

Funkcija Makecounter () (
var currentcount \u003d 0;

Atgriešanās funkcija () (
Izplatīšanas daļa ++;
Atgriezties currentcount;
};
}

Var counter \u003d makeCounter ();
Skaitītājs ();
Skaitītājs ();
Brīdinājums (counter ()); // 3.

Iebildums JavaScript funkcijas Var aprakstīt ne tikai vienu pēc otra, bet arī viens no otra. Ja jums ir viena funkcija, iekšpusē iekšienē ir piekļuve pārmaiņām ārējai funkcijai.

Funkcija ārējā (x) (var tmp \u003d 3; funkcija iekšējais (Y) (brīdinājums (x + y + (++ tmp)); // noņem 16) iekšējo (10);) ārējs (2);

Šis kodekss vienmēr dod 16, jo iekšējā funkcija redz X, kas ir mainīgs funkcijā. Iebildums Šis gadījums Argumentu funkcija. Arī iekšējais () var redzēt TMP no ārējās ().

To sauc slēgšana vai slēgšana. Ja precīzāk, slēgšana tiek saukta par ārējo funkciju, un viss iekšpusē to sauc par slēgšanas vidi vai slēgšanas vidi.

Dažreiz ir teikts, ka slēgšana ir funkcija, kas atgriež funkciju, tas ir nepareizi, lai nosauktu slēgšanas funkciju, ko iekšējā funkcija attiecas uz mainīgo no tās darbības jomas.

Funkcija Foo (X) (VAR TMP \u003d 3; atgriešanās funkcija (y) (brīdinājums (x + y + (++ TMP)); // arī brīdinās 16)) var bārs \u003d foo (2); // bārs tagad ir slēgšana. Bārs (10);

Iepriekš minētā funkcija arī parādīsies 16, jo bārs pat pēc foo pabeigšanas turpina piekļūt X un TMP, pat tad, ja bārs mainīgais pats nav iekšā, kurā tie tika deklarēti.

Tajā pašā laikā, jo TMP mainīgais joprojām ir bāra slēgšanas iekšpusē, tas turpina palielināt katru laika joslas zvanu.

Šeit vienkāršākais piemērs Ķēde:

Var a \u003d 10; Funkcijas tests () (Console.log (A); // Secinājums 10 Console.log (b); // secinājums 6) var b \u003d 6; pārbaude ();

Kad sākat funkciju JavaScript, videi ir izveidota tā, tas ir, saraksts ar visu mainīgo redzamo tai, ne tikai argumentiem un mainīgajiem, kas to paziņoja tajā, bet arī ārpusē, šajā piemērā tas ir "a "un" b ".

Jūs varat izveidot vairāk nekā vienu aizvēršanu vienā vidē, atgriežot tos masīvam, objektam vai pievienojot globālu mainīgo. Šajā gadījumā viņi visi strādās ar tas pats X vai TMP vērtība, neradot atsevišķas kopijas.

Tā kā mūsu piemērā X ir numurs, tad tā vērtība kopija Foo kā argumentu X.

No otras puses, JavaScript vienmēr izmanto saites, kad objekti tiek pārraidīti. Ja jūs saucat foo ar objektu kā argumentu, tad atgriešanās slēgšana atgriezīs saiti uz sākotnējo objektu!

Funkcija Foo (x) (VAR TMP \u003d 3; atgriešanās funkcija (Y) (brīdinājums (X + Y + TMP); X.MEMB \u003d X.MEMB? X.memb + 1: 1; Alert (X.memb);) ) Var vecums \u003d numurs (2); var bārs \u003d foo (vecums); // bārs tagad ir slēgšana, kas attiecas uz vecumu. Bārs (10);

Kā paredzēts, katrs zvanu josla (10) palielinās X.memb. Ko jūs varētu negaidīt, tāpēc X turpina atsaukties uz to pašu objektu kā vecumu! Pēc diviem zvanu bāriem vecums.memb būs vienāds ar 2! Starp citu, notiek atmiņas noplūde HTML objektos.

Programmēšana, slēgšana vai angļu valodas versijā "Noslēguma" ir metode konteksta saistošā nosaukuma ieviešanai pirmās klases funkcijās. Operatīvi, tas ir ieraksts, kas saglabā funkciju kopā ar vidēju. Vide ir katra bezmaksas funkcijas salīdzinājums ar vērtību vai atsauci, ko sauc par JavaScript aizvēršanu. Tas ļauj piekļūt notvertajiem mainīgajiem, izmantojot vērtību vai saites kopijas, pat ja tas izraisa ārpus reģiona.

Slēgšanas jēdziens

Noslēgumi tika izstrādāti 60. gados, lai aprēķinātu mehānisku novērtējumu aprēķināšanā un 1970. gadā piemērota kā PAL programmēšanas valodas iezīme, lai atbalstītu pirmās klases funkcijas ar leksisko sfēru. Peter Landin definēja terminu "slēgšana" 1964. gadā ar vidēja un kontroles daļu, ko izmanto SECD mašīnā, lai novērtētu Lambda izteiksmes, kas saistītas ar leksisko vidi, kas noveda pie aizverot tos vai slēgt JavaScript.

Šāds paskaidrojums tika iekļauts 1975. gadā kā leksiski ierobežota Lisp versija un bija plaši izplatīta. Leksiskā vide programmā ir dažādi derīgi mainīgie lielumi. Tā sastāv no iekšējās leksikas vides un atsauces uz ārējo vidi, ko sauc par netraucētu mainīgajiem.

Leksu slēgumi JavaScript ir funkcijas ar ārējo vidi. Tāpat kā JavaScript, visi mainīgie ir saite uz veidu. JS izmanto tikai saistību ar atsauci - kas atbilst C ++ 11, un funkcijas ne-vietējo mainīgo mūža ilgums tiek sadalīts funkcijas kalpošanas laikā.

JavaScript shēmas parasti parādās valodās ar pirmās klases vērtībām. Šādas valodas ļauj pārsūtīt funkcijas kā argumentus. Un arī atgriezieties no funkciju zvaniem un pievienojiet mainīgajiem nosaukumiem. Tas notiek kā vienkāršie veidi, piemēram, virknes un veseli skaitļi.

Šajā piemērā, Lambda Expression (Lambda (\u003e \u003d (grāmatu-pārdošanas grāmata) slieksnis) parādās iekšpusē labākās pārdošanas-grāmatu funkciju. Kad Lambda izteiksme tiek aprēķināta, ķēde izveido slēgšanu, kas sastāv no koda izpausmes lambda un atsauces uz sliekšņa mainīgo, kas ir bezmaksas mainīgais Lambda izteiksmē. Pēc tam slēgšana tiek pārraidīta ar filtra funkciju, kas to atkārtoti izraisa, lai noteiktu, kuras grāmatas jāpievieno rezultātu sarakstam un kas jāiznīcina.

Tā kā sliekšņa vērtībā ir slēgšana, tā to var izmantot katru reizi, kad tās filtra cēloņi. Filtra funkciju pats var definēt perfekti atsevišķs fails. Šeit ir tas pats piemērs, pārrakstīts JS. Tas parāda, kā slēgumi zem pārsega JavaScript darbā.

Atslēgvārds šeit tiek izmantots globālās filtra funkcijas vietā, bet pārējā struktūra un koda ietekme ir vienāda. Funkcija var radīt tuvāk un atgriezt to, jo tas šajā gadījumā piedzīvo funkcijas izpildi ar mainīgajiem lielumiem F un DX turpina darboties pēc atvasinājuma, pat ja izpilde atstāja to darbības jomu, un tie vairs nav redzami.

Valodās bez slēgšanas, automātiskās vietējā mainīgā kalpošanas laiks sakrīt ar steku rāmja izpildi, kur šis mainīgais ir deklarēts. Valodās ar JavaScript, iife slēgumiem un funkcijām mainīgajiem lielumiem ir jāturpina pastāvēt, līdz kādām esošajām slēdzenēm ir atsauces uz tiem. Tas visbiežāk tiek īstenots, izmantojot kādu atkritumu savākšanas formu.

Aizsardzības priekšrocība ir tā, ka tā saglabā ārējās vai "vecāku" izpildes kontekstā "darbības jomu," ķēdi redzamību ". Šādu rīcību var izmantot vairākos veidos un ir kļuvis par noderīgu rīku, lai novērstu dažādas JavaScript kļūdas. Viens no visbiežāk ir problēma "cilpas".

Cikla problēma rodas, kad lietotājs izveido funkciju ciklā, un sagaida pašreizējo vērtību mainīgo šajā jauna funkcijaPat ja tas mainās ciklu kontekstā pirms jauna funkcijas izsaukšanas. Šādā veidā izmantotajiem slēgumiem vairs nav atsauces pārredzamības, un tāpēc vairs nav tīras funkcijas, tās parasti izmanto nešķīstības funkcionālajās valodās, piemēram, shēmā. Lai saprastu, kas ir aizvērts JavaScript, jums ir jāapsver lietošanas gadījumi. Faktiski, praksē, viņiem ir daudz pieteikumu:

  1. Tos var izmantot, lai noteiktu kontroles struktūras. Piemēram, visas standarta MazoTalk vadības struktūras, tostarp filiāles (ja / tad / cits) un cikli (kamēr un), tiek noteikts, izmantojot objektus, kuru metodes ņem slēgšanu. Lietotāji var arī viegli izmantot slēgumus, lai noteiktu kontroles struktūru. Valodās, kas īsteno mērķi, jūs varat izveidot savu daudzfunkcionālo vidi, ļaujot jums konfidenciāli sazināties un mainīt šo vidi. Slēgšana tiek izmantota, lai īstenotu objektu sistēmas.
  2. Gan privāto, gan publisko mainīgo metožu izveide, izmantojot moduļu veidnes. Sakarā ar to, ka atgriezās iezīmes manto mātes funkcijas platību, tie ir pieejami visiem mainīgajiem lielumiem un argumentiem šajā kontekstā.
  3. Tas ir noderīgi situācijā, kad funkcija izmanto to pašu resursu katram zvanam, bet arī izveido resursus pats par to. Šis apstāklis \u200b\u200bpadara metodi neefektīvu, kas tiek likvidēta tikai slēgšana.

Saskaņā ar MDN (Mozilla izstrādātāju tīklu) "slēgšana ir funkcijas ar neatkarīgiem mainīgajiem, ka" atcerēties "tās radīšanas vidi." Un, kā likums, kad funkcija ir pabeigta, tās vietējie mainīgie vairs nepastāv. Izprast, kā slēgšana JavaScript darbos jūs varat apsvērt vairākus mehānismus. Pirmais ir oficiāls loģika. Piemēram, piemērojot logname funkciju, kas aizņem vienu nosaukumu kā parametru un reģistrē to. Tad es izveidoju ciklu, lai pārietu uz vārdu sarakstu, iestatiet 1. taimautu, un pēc tam zvaniet uz logname funkciju, kas iet pašreizējā nosaukumā.

Pirmās klases valodā jūs varat manipulēt tāpat kā cita veida datus, piemēram, int vai virkni. Tikai šis mehānisms ļauj daudziem izveidot neticamas lietas, piemēram, piešķirt mainīgo funkciju nākamajam zvanam vai nosūta to kā citas funkcijas parametru.

Šo principu izmanto daudzas struktūras, kā arī Dom notikumu apstrādātāji. Pirmkārt, pasākums ir "klausīšanās", pēc tam piešķirt atzvanīšanas funkciju, kas tiks saukta katru reizi, kad notikums tiek aktivizēts.

Anonīma funkcija ir funkcija bez nosaukuma. Praktiski iesācēji programmētāji satiek tos katru dienu, nesaprotot spēli ar numuriem. Piemēram, veicot papildināšanas darbību, jūs varat iet caur mainīgajiem lielumiem, piemēram:

  • var x \u003d 3;
  • y \u003d 5;
  • var z \u003d x + y.

Vai ja jūs neplānojat atkārtoti apstrādāt numurus: var Z \u003d 3 + 5;

Tie ir anonīmi numuri. Anonīmām funkcijām jūs varat tos pasludināt, kad tos izmanto "uz lidojuma" - neizmantojot mainīgo. Piemēram, veiciet funkciju no iepriekš:

(Brīdinājums ("Ceci Est UNE fonchan anonyme");

Turklāt ir alternatīvs sintakse par funkcijas deklarāciju, kas uzsver, ka abas funkcijas var būt anonīmas un attiecas uz vienkāršiem mainīgajiem lielumiem, kas ir ērts veids, kā instalēt atzvanīšanas funkciju.

Faktiski tas ir tas pats mehānisms, bet no šī viedokļa tas ļaus jums redzēt, kā funkcija ir slēgta no iekšpuses. Kā redzams, jo funkcijas ir mainīgie, tāpat kā citi, nav iemesla, kādēļ tās nevar noteikt lokāli. Nulles secībā, piemēram, C, C ++ un Java, visas funkcijas tiek noteiktas vienā redzamības līmenī vienā un tajā pašā klasē vai pasaules līmenī. No otras puses, JavaScript vietējā funkcija pazūd, kā arī citi vietējie mainīgie lielumi, tiklīdz vecāku funkcija beidzas, tāpēc tas nav redzams no citām funkcijām.

Tas ir patiešām grūti, bet JavaScript ir veids, kā izsekot mainīgumu redzamību un pat divos veidos. Globālā mainīgā lieluma piešķiršana JavaScript ir tāds pats mehānisms kā Java - sarežģītiem objektiem, masīviem, Dom elementiem un citiem tiek nosūtīti pēc atsauces, tāpēc šādā kodā:

var cilne \u003d; Var TAB2 \u003d cilne.

Kur, cilne un Tab2 ir divas saites uz to pašu tabulu, tehniski tie ir rādītājs, ko kontrolē atkritumu savācējs. Funkcijas tiek nosūtītas arī pēc atsauces. GlobalFn mainīgais vairs nav slēpts. Rīkojums ļauj jums darīt to, kas ir pierādīts par JavaScript slēgšanas uzdevuma piemēru.

Tādā veidā jūs varat iegūt funkciju no vietējā konteksta, ja funkcija atbilst citiem vietējiem mainīgajiem lielumiem. Vienkāršs piemērs: auto-pieaugums, funkcija, kas atgriež veselu skaitli, kas palielinās par 1 katru reizi. Konkrēti, INC funkciju vajadzības, kas uzvedas šādi:

// retourne 0 inc ();

// retourne 1 inc ();

// retourne 2 inc ();

Ar slēgšanu izskatās:

funkcijas mehekcijai () (VAR X \u003d 0; atgriešanās funkcija () (atgriešanās x ++;)) Var Inc \u003d makeCom ();

Pēdējā rindā brīdī, kad tiek izveidots INC mainīgais, tas veic dažus mainīgos lielumus, kas ir apkārt, šajā gadījumā x. Tas rada noteiktu neredzamu objektu ap funkciju, kas satur šo mainīgo. Šis objekts ir JavaScript slēgšanas funkcija. Tajā pašā laikā katrai funkcijas kopijai būs savs slēgums:

var inc1 \u003d makets ();

var inc2 \u003d makets ();

Kā redzams, slēgšana daudzos gadījumos ir ļoti noderīga.

Lai izvairītos no mainīgajiem nosaukuma konfliktiem, parasti izmanto vārdnīcu. JavaScript nosaukumvietas ir tādi objekti kā jebkurš cits.

Protams, A.x un B.X nav tāds pats mainīgais. Tomēr, ja jums vienkārši ir jāsāk skripts, neprasot taupīšanas mainīgos lielumus pārējo, anonīmu funkciju var izmantot kā slēgšanu. Tas dod nedaudz dīvainu sintaksi. Lai gan divi kodi vidū ir diezgan izplatīti, no otras puses, funkcija, kas ir aptuveni tiek veikta "lidojumā". Pievērsiet uzmanību iekavām () beigās. Un lai varētu veikt slēgšanu, anonīma funkcija Pati ir jāvēršas ar apaļiem kronšteiniem.

Šajā anonīmā funkcija izmanto vietējo mainīgo punktu. Tas ir lielisks veids, kā novērst vārda konfliktus vai vainu, bet arī pret aTAKS XSS. Pielāgoti mainīgie ir aizsargāti, neviens nevar mainīt tās, lai ietekmētu uzvedību skriptu.

Ir iespēja: (funkcija () (// ...) ());

Tajā pašā laikā pievērsiet uzmanību iekavām. Starpība starp šīm divām iespējām ir diezgan grūti izskaidrot, jo tās ir saistītas ar kodu lasa leksikas analizators. Abos gadījumos funkcija tiek uzskatīta par izteiksmi, bet šī izteiksme netiek lēsta vienlaicīgi. Vienkārši jāatceras, ka viņš aizņem divus apaļu kronšteinu pārus: vienu no funkcijas un viens aiz tā.

JavaScript programmēšana ciklos

Kad lietotājs veic lielus JavaScript programmēšanas apjomus, tam ir grūti izvairīties no cikliem. Kāds ir traks, pēc tam viņi nonāk pie idejas, ka JavaScript īstenošanai ir nopietna kļūda. Ja izstrādātājam jau ir cikls, ko viņš nevēlas konvertēt, lai izmantotu iteratora funkciju, viss, kas viņam jādara, ir slēgšana, kurā tas definē jaunus mainīgos lielumus. Tie nosaka mainīgo lielumu pašreizējo vērtību un atšķiras katrā iterācijā. Triks, lai uztvertu mainīgos lielumus, ir tas, ka ārējais slēgums tiek veikts tieši cikla pašreizējā iterācijas laikā. Jūs varat izmantot kādu no šīm divām aptuvenām pieejām.

Tagad ir vēl viens vienkāršots risinājums šai problēmai, jo atslēgvārds tiek atbalstīts gan Firefox, gan Chrome. Tas ir atslēgvārds Var mainīt mainīgo bloku. Ļaujiet darboties maģiski, jo jauns mainīgais j tiek deklarēts, kuras vērtība ir noteikta ar slēgšanu ciklā. Tomēr jāpatur prātā, ka tas nav turpināt pastāvēt pēc tā paša cikla atkārtošanas beigām, jo \u200b\u200btas ir lokāli.

Cilpa un funkcija

Par cilpu JavaScript neparādās, kā arī cik ciklu C vai Java. Patiesībā, tas izskatās vairāk kā PHP. Svarīgākās zināšanas par js cikliem ir tas, ka tie nerada darbības jomu. JS nav sfēras bloka, tikai apjoma funkcija. Šo īpašumu var uzskatīt par šādu fragmentu:

funkcija Foo () (Var Bar \u003d 1;

par (var i \u003d 0; i< 42; i++) {var baz = i;} /* more code */}

Ir skaidrs, ka bārs ir pieejams visā funkcijā. Pirms Pirmā Baz cikla atkārtošanās būs nenoteikta. Pēc cikla tas būs vērtība 41 (un es būšu 42). Tādējādi jebkurš mainīgais, kas deklarēts jebkurā funkcijā, būs pieejams visur funkciju un būs derīga tikai pēc tam, kad tā tika iecelta Viņam.

Slēģi un apkopošana

Slēgšana nav nekas vairāk kā funkcijas, iekšpusē citās funkcijās, un tiek nosūtīti uz kādu citu kontekstu. Tos sauc par slēgšanu, jo tie aizveras caur vietējiem mainīgajiem lielumiem, kas ir pieejami citām jomām sfērā. Piemēram, laiks, x definēts kā foo parametrs, un var bārs \u003d foo (2) () atgriezīsies 84.

Atgrieztā foo funkcija ir piekļuve x. Tas viss ir svarīgi, jo tas palīdz izstrādātājiem izveidot funkcijas iekšējos ciklos atkarībā no cikla mainīgajiem. Apsveriet šo fragmentu, kas piešķir klikšķu procesoru dažādiem elementiem:

// elementi ir 3 Dom elementu klāsts VAR vērtības \u003d ["foo", "bārs", "BAZ"];

i.< l; i++) {var data = values[i];

elementi [i] .Inclick \u003d funkcija () (brīdinājums (dati);

Vērtība, ko viņi izmantos brīdinājumu, kad nospiests, būs tas pats visiem, proti, Baz. Līdz tam laikam notikumu apstrādātājs jau ir pabeigts. JS nav bloka apgabala, t.i. Visi apstrādātāji izmanto saiti uz to pašu datu mainīgo. Pēc cilpas šī vērtība būs vērtības. Katra mainīgā deklarācija rada vienu vietu atmiņā. Par, šis dati tiek mainīts atkal un atkal, stāvoklis atmiņā paliek nemainīga.

Katram notikumu apstrādātājam ir piekļuve tai pašai pozīcijai atmiņā. Vienīgais risinājums ir ievadīt citā apgabalā, kas "nosaka pašreizējo datu vērtību. JS ir tikai dažādas funkcijas. Tāpēc tiek ievadīta vēl viena funkcija. Piemērs:

funkcija Createeventhandler (x) (atgriešanās funkcija () (brīdinājums (x);

par (var i \u003d 0, l \u003d elementi.length;

i.< l; i++) {var data = values[i];

elementi [i] .Oclick \u003d Createeventhandler (dati);

Tas darbojas, jo datu vērtība tiks saglabāta vietējā teritorijā, Createeventhandler un šī funkcija tiek veikta katrā iterācijā. To var rakstīt īsi, izmantojot izpildāmās funkcijas uzreiz:

par (var i \u003d 0, l \u003d elementi.length;

i.< l; i++) {var data = values[i];

elementi [i] .Inclick \u003d (funkcija (x) (funkcija () (brīdinājums (x);

Praktiskais slēgšanas piemērs JavaScript

Ja lietotājs veic aizvēršanu tieši virs koda pārlūkprogrammā, tas var saskarties ar problēmu, jo tā var veikt jebkuru sintakses kļūdu. Ja tā izpilda kodu tieši pārlūkprogrammā, izredzes ir ļoti augstas, lai apkopotu webpack apkopošanas procesu. Iespējamie risinājumi:

funkciju darbs (nosaukums) (

atgriešanās funkcija (tēma) (

konsole.Log (kas ir $ (temats) $ (nosaukums));

darbs ("JavaScript") ("slēgšana");

Pirmkārt, funkcija tiek saukta un tiek nosūtīts nosaukums arguments. Tagad šī vārdnīcas funkcija arī atgriež funkciju, kas arī pieņem tēmu argumentu. Šī funkcija reģistrē izeju, un izejai ir piekļuve mainīgajam.

Iestādes funkciju apgabals neaprobežojas ar šo funkciju, tāpēc koncepciju sauc par slēgšanu, jo tai ir piekļuve šai teritorijai ārējais parametrs. Atgrieztā funkcija ir piekļuve ārējai leksikas zonai vai kontekstam. Kad attīstītājs aicina funkciju, kas to atgriež, tad vispirms sauc mainīga funkcija Vienmēr ir pieejams iekšējai funkcijai. Turklāt piemērs ar šādu kodu.

Iekšējās funkcijas piemērs

Lasīt vairāk par slēgšanu JavaScript var pastāstīt par otro piemēru. Tagad šī izpildes vide tiek iznīcināta, bet parametra nosaukums joprojām pastāv. Ir izveidots jauns iekšējais funkcionālais līdzeklis, kas ir anonīma funkcija. Tai ir piekļuve ārējās leksiskās vides teritorijai.

Tādējādi, mainīgā ārējā vidē, tā joprojām pastāv tādā veidā, ka anonīmai funkcijai ir piekļuve nosaukuma mainīgo izdruku konsolē, piemēram, "Kas ir slēgšana JavaScript". Iekšējā anonīma funkcija //main.js

funkciju fabrika () (VAR produkti \u003d;

i ++) (products.Push (funkcija () (konsoles.log (i);

) Atgriešanās produkti;

) Var ziepes \u003d rūpnīca ();

Šī piemēra rezultāts ir diezgan nenozīmīgs un vienāds ar 2.

Kad ziepes ir ziepes (), ko sauc par ārējo konteksta mainīgo, vienmēr 2, jo ciklā stāvoklis ir nepatiess i<2, поэтому при этом значение i равно 2, а во время вызова нужно напечатать значение в консоль так, она всегда пишет 2. То же самое для мыла - soap ().

Funkciju izveide "lidojumā"

Varat izveidot funkcijas fabrika - funkcijuFactory, kas veic pielāgotus uzdevumus. Iegūtā funkciju funkcija būs slēgšana, uzglabāšanas līdzekli.

var funkcionāls \u003d funkcija (NUM1) (atgriešanās num1 * NUM2;

Iepriekš minētie ļauj pārsūtīt vienu funkciju skaitu. Tad funkcijaFactory atgriež slēgšanu, atceroties num1 vērtību. Iegūtā funkcija reizina sākotnējo num1 reizes vērtību num2, kas tiek nosūtīts, kad to sauc.

var mult5 \u003d funkcionāla (5);

var mult10 \u003d funkcionāla (10);

Iepriekš vienkārši izveido mult5 un multo10 funkcijas. Tagad jūs varat atsaukties uz kādu no šīm funkcijām, nododot jaunu numuru, lai reizinātu ar 5 vai 10. Tagad jūs varat redzēt rezultātu.

Slēgšana ir viens no spēcīgākajiem JavaScript funkcijām, bet to nevar izmantot pareizi, nesaprotot būtību. Tie ir salīdzinoši viegli izveidot nejauši, tas ir tas, kā bīstami slēgt JavaScript. Viņu radīšana ir potenciāli kaitīga ietekme, jo īpaši dažās salīdzinoši kopējās tīmekļa pārlūkprogrammas vidēs. Lai izvairītos no nejaušas sadursmes ar trūkumiem un izmantojiet priekšrocības, ko viņi piedāvā, ir nepieciešams saprast savu mehānismu.

Šajā rakstā es centīšos izskaidrot redzamības jomas un slēgšanu JavaScript, kurā daudzās grūtības ir grūtības.

Ieviešana

Ir diezgan daži raksti tīklā, kas cenšas izskaidrot redzamības un slēgšanas jomas, bet kopumā es teiktu, ka lielākā daļa no tām nav pilnīgi saprotamas. Turklāt dažos rakstos tiek pieņemts, ka jūs esat ieprogrammēts pirms 15 citām valodām, lai gan es domāju, ka lielākā daļa cilvēku rakstot uz JavaScript ir tikai pieredze HTML un CSS, nevis C vai Java.

Līdz ar to šī panta mērķis ir izskaidrot visu - kāda ir redzamības un slēgšanas apjoms, jo tie darbojas, un vissvarīgāk, kāda ir viņu priekšrocība. Pirms šī raksta izlasīšanas jums ir jāzina pamatjēdzieni par mainīgajiem lielumiem un funkcijām JavaScript.

Redzamības zona

Darbības joma nozīmē, kur ir pieejami mainīgie un funkcijas, un tādā kontekstā tie tiek izpildīti. Mainīgo vai funkciju var definēt globālā vai vietējā redzamības jomā. Mainīgie lielumi ir tā sauktā funkcija funkciju redzamību, un funkcijas ir tāda pati darbības joma kā mainīgie.

Globālā darbības joma

Kad kaut kas ir globāls, tas nozīmē, ka tas ir pieejams jebkurā jūsu koda vietā. Apsveriet piemēru:

var mērkaķis \u003d "gorilla"; Funkcija apsveikums () (atgriešanās brīdinājums ("Sveiki Dārgie emuāra lasītājs!");)

Ja šis kods tika veikts tīmekļa pārlūkprogrammā, tad redzamības joma būtu logs, tad tas būs pieejams visam, kas tiek izpildīts logā.

Vietējā darbības joma

Atšķirībā no globālās redzamības zona, vietējā redzamības joma ir tad, kad kaut kas ir definēts un pieejams tikai kādā koda daļā, piemēram, funkciju. Apsveriet piemēru:

funkcija rundirty () (var sakot \u003d "Ak, jūs maz vb mīļākais, jūs, atgriežat brīdinājumu (sakot);) brīdinājums (sakot); // izmet kļūda

Šajā piemērā, sakot mainīgais ir pieejams tikai iekšpusē rundirty funkciju, ārpus tās tas nav definēts. Piezīme: Ja jūs identificētu, sakot bez var atslēgvārdu, tas automātiski kļūtu globāls.

Turklāt, ja jums ir ligzdotas funkcijas, iekšējai funkcijai būs piekļuve funkcijām, kurās tas ir iebūvēts, kā arī mainīgie:

funkcija Capitalizename (atgriešanās firstname.tuppercase ();) var kapitalizēt \u003d capitalizename (); atgriešanās kapitalizēts; brīdinājums (Savename ("Robert")); // atgriež "Robert"

Kā jūs tikko redzējāt, iekšējā funkcija Capitalizename nav nepieciešams, lai nosūtītu visus parametrus, jo Tai ir pilnīga piekļuve pirmvārda parametram savenama ārējā funkcijā. Lai iegūtu lielāku skaidrību, apsveriet citu piemēru:

funkciju brāļi un māsas () (Var brāļi un māsas \u003d ["John", "Liza", "Pēteris"]; Funkcija SiblingCount () (VAR SIBLINGSLENCE \u003d brāļi un māsas. () + "Brāļi un māsas: nn" + s māsas.join ("n");) atgriezties Joinsiblingnames ();) Brīdinājums (brāļi un māsas ()); // izejas "Man ir 3 brāļi un māsas: John Liza Peter"

Kā redzat, abām iekšējām funkcijām ir piekļuve brāļiem un māsu masīvam, un katrai iekšējai funkcijai ir piekļuve citai iekšējai vienāda līmeņa funkcijai (šajā gadījumā, Joinsiblingnames ir piekļuve sibingCount). Tomēr siblingslength mainīgais iekšpusē SiblingCount ir pieejama tikai šajā funkcijā, t.i. Šajā redzamības jomā.

Ķēde

Tagad, kad jums ir skaidrāka ideja par redzamības jomām, mēs pievienosim slēgšanu tiem. Ķēdes ir izteiksmes, parasti funkcijas, kas var strādāt ar kopumu mainīgajiem noteiktā kontekstā. VAI, vienkāršāki vārdi, iekšējās funkcijas, kas attiecas uz vietējiem mainīgajiem ārējo funkciju veido slēgšanu. Piemēram:

funkcija pievieno (x) (atgriešanās x + y;);) var pievienot 5 \u003d pievienot (5); var no8 \u003d ADD5 (3); Brīdinājums (NO8); // atgriežas 8.

Blimey! Kas šeit notiek? Apdomēsim:

1. Kad mēs saucam pievienošanas funkciju, tā atgriež funkciju.

2. Šī funkcija aizver kontekstu un iegaumē, kā parametrs X ir šajā laikā (t.i., šajā gadījumā vērtība 5)

3. Kad pievienošanas funkcijas rezultāts ir piešķirts pievienojumprogrammas mainīgajam, tas vienmēr zinās, ko X bija, veidojot šo mainīgo.

4. Mainīgais ADD5 attiecas uz funkciju, kas vienmēr pievienos vērtību 5 jebkuram tai nosūtītajam argumentam.

5. Tas nozīmē, ka tad, kad mēs saucam ADD5 ar vērtību 3, tas noliecās skaitu 5 un 3, un atgriezīsies 8.

Faktiski, JavaScript pasaulē, Add5 funkcija izskatās šādi:

funkcija ADD5 (Y) (atgriešanās 5 + y;)

Bēdīgs ciklu problēma
Cik reizes jūs izveidojāt ciklus, kuros jūs vēlējāties piešķirt vērtību i jebkādā veidā, piemēram, elements, un saprot, ka tikai pēdējā vērtība, ko es atgriezāmu?

Nepareizsapelācija

Apskatīsim šo nepareizo kodu, kas rada 5 elementus , pievieno vērtību i kā tekstu katram elementam un onclick, kas paredzēts, lai radītu brīdinājumu ar vērtību i par šo atsauci, t.i. Tāda pati vērtība kā elementa tekstā. Tad elementi tiek pievienoti dokumentu korpusam:

<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function () { alert(i); }; document.body.appendChild(link); } } window.onload = addLinks;

Katrs elements satur pareizo tekstu, t.i. "LINK 0", "LINK 1" utt. Bet neatkarīgi no tā, ko jūs noklikšķinājāt, tas parāda brīdinājumu ar numuru 5. Kas ir jautājums? Iemesls ir tas, ka mainīgās vērtības es palielinās par 1 ar katru cikla atkārtojumu, un tāpēc, ka OnClick notikums netiek izpildīts, bet vienkārši attiecas uz elementu Vērtība palielinās.

Tāpēc cikls turpina strādāt, līdz es kļūšu vienāds ar 5, kas ir pēdējā vērtība pirms došanās no AddLinks funkciju. Turklāt katru reizi, kad tiek aktivizēts OnClick notikums, pēdējā vērtība, ko es pieņemu.

Pareiza apelācija

Kas jums jādara, ir izveidot slēgšanu. Tā rezultātā, kad jūs piemērojat vērtību i uz OnClick notikumu notikumu , Man tajā laikā tiks piešķirta I vērtība. Piemēram, šādi:

funkcija AddLinks () (par (var i \u003d 0, saite; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function (num) { return function () { alert(num); }; }(i); document.body.appendChild(link); } } window.onload = addLinks;

Izmantojot šo kodu, ja noklikšķināt uz pirmā elementa, brīdinājums izdod "0", otrajā - "1" utt. Risinājums ir tāds, ka iekšējā funkcija, ko piemēro OnClick notikumam, rada slēgšanu, kurā numperimer ir parametru pārsūdzības, i.e. uz I vērtību tajā laikā.

Šī funkcija "atceras" vēlamo vērtību, un pēc tam var atgriezt atbilstošo ciparu, kad tiek aktivizēts OnClick notikums.

Drošas izpildes funkcijas

Safe-izpildes funkcijas ir tādas funkcijas, kas sāk veikt nekavējoties un radīt to slēgšanu. Apsveriet piemēru:

(Funkcija () (VAR suns \u003d "vācu aitu"; brīdinājums (suns);)) (); Brīdinājums (suns); // atgriežas nenoteikts.

Tātad, suņu mainīgais ir pieejams tikai šajā kontekstā. Padomājiet, slēpto mainīgo suni ... bet, mani draugi, visvairāk interesanti lieta sākas ar šo! Tā atrisināja mūsu problēmu ar ciklu, un tas ir arī pamats Yahoo JavaScript moduļa modulim.

Yahoo JavaScript moduļa modelis

Šī modeļa būtība ir tā, ka tā izmanto drošu izpildāmu funkciju, lai izveidotu slēgšanu, tāpēc tas ļauj izmantot privātās un publiskās īpašības un metodes. Vienkāršs piemērs:

vAR PERSON \u003d FUNCTION () (// Private VAR NAME \u003d "ROBERT"; Atgriezties (GetName: Funkcija () (atgriešanās nosaukums), Setname: Funkcija (Newname) (nosaukums \u003d NewName;));) (); brīdinājums (cilvēks); // undefined brīdinājums (persona.getname ()); // "robert" persona.Setname ("Robert Nyman"); brīdinājums (person.getname ()); // "Robert Nyman"

Šīs pieejas priekšrocība ir tā, ka jūs varat definēt sevi, kas būs atvērts jūsu objektā (un to var mainīt), un tas ir slēgts, kuru neviens nevar sazināties vai mainīt. Nosaukuma mainīgais ir paslēpts ārpus funkcijas konteksta, bet ir pieejama GetName un Setname funkcijām, jo Tie rada slēgumus, kuros ir saite uz nosaukuma mainīgo.

Secinājums

Es patiesi ceru, ka pēc iepazīšanās ar šo rakstu, jaunpienācēji un pieredzējuši programmētāji saņēma skaidrāku priekšstatu par to, kā JavaScript darba vietās redzamību un slēgšanu. Jautājumi un atsauksmes ir apsveicami, un, ja jums ir kaut kas svarīgs, lai kaut ko ļautu, tad es varu atjaunināt rakstu.

Laba kodēšana!

Ķēdes JavaScript. Izmanto, lai paslēptu mainīgās vērtības un veikalu funkcijas. Punkts ir tāds, ka tad, kad ir izveidota viena funkcija, kurā ir norādīti mainīgie lielumi un kas tā darbības rezultātā atgriež savu ligzdoto funkciju. Tad tajā (galvenajā funkcijā) ir izveidota iegultā funkcija, kurā dažas darbības tiek veiktas ar mainīgiem funkciju mainīgajiem un kas atgriež šo darbību rezultātu. Tālāk galvenā funkcija ir vienāda ar mainīgo - šo mainīgo var izsaukt, cik daudz laika un tomēr tiks saglabāta un atjaunināta galvenās funkcijas mainīgo lielumu vērtības. Viņa ir slēgta. "

Kā jūs zināt, JavaScript vietējo mainīgo redzamības laukā (deklarēts VAR Word) Tā ir funkcijas ķermenis, kurā tie ir definēti.

Ja jūs deklarējat funkciju iekšpusē citā funkcijā, pirmais saņem piekļuvi mainīgajiem un argumentiem tā:

Kods: Funkcija Outerfn (Myarg) (
Var myvar;
Funkcija Innerfn () (
// ir piekļuve myvar un miarg
}
}

Tajā pašā laikā šādi mainīgie lielumi joprojām pastāv un paliek pieejami iekšējā funkcija pat pēc ārējās funkcijas, kurā tie ir definēti, tika izpildīts.

Apsveriet piemēru - funkciju, kas atgriež skaitu eigenvalues:

Kods: Funkcija CreateCounter () (
varofcalls \u003d 0;
Atgriešanās funkcija () (
Atgriezties ++ numurs;
}
}
var fn \u003d createCounter ();
fn (); // viens
fn (); // 2.
fn (); // 3.

Šajā piemērā, funkcija, kas tiek atgriezta ar CreateCounter izmanto numerofcalls mainīgo, kas ietaupa vēlamo vērtību starp saviem zvaniem (nevis nekavējoties pārtraukt tās esamību ar CreateCounter atgriešanos).

Šīm īpašībām ir šādas "ligzdotās" funkcijas JavaScript tiek saukta par slēgšanu (termins, kas nāca no programmēšanas funkcionālajām valodām) - tie "ciešāk" mainīgie un argumenti funkciju, kas ir definēti.

Slēgšanas pieteikums

Vienkāršo nelielu piemēru iepriekš - noņemiet nepieciešamību atsevišķi izsaukt CreateCounter funkciju, padarot to pielikumu un aicinot to pēc tās reklāmas:

Kods: VAR FN \u003d (Funkcija () ()
varofcalls \u003d 0;
Atgriešanās funkcija () (
Atgriezties ++ numurs;
}
})();

Šāds dizains ļāva mums saistīt datus funkcijai, kas palika starp tās izaicinājumiem, ir viens no aizvēršanas veidiem. Citiem vārdiem sakot, ar viņiem palīdzību mēs varam izveidot funkcijas, kurām ir mainīga valsts.

Cita laba slēgšana - funkciju izveide, savukārt, arī izveidojot funkcijas - ko daži tiks saukti par T.N. Metaprogrammēšana.
Piemēram:

Kods: VAR Createhellofunction \u003d Funkcija (nosaukums) (
Atgriešanās funkcija () (
Brīdinājums ("Hello" + nosaukums);
}
}
var teikthellohabrahabr \u003d createhellofunction ("habrahabr");
sayhellohabrahabr (); // brīdinājumi "Sveiki, Habrahabr"

Pateicoties slēgšanai, atgrieztā funkcija "atceras" parametrus, kas pārnesti uz funkcijām, kas radīs, ka mums ir vajadzīga šāda veida lietām.

Līdzīga situācija rodas, ja mēs neatgriežam iekšējo funkciju, un pakārt jebkurā gadījumā - tā kā notikums rodas pēc tam, kad funkcija ir izpildīta, slēgšana atkal palīdz nezaudēt datus, kad datu apstrādātājs ir izveidots.

Apsveriet nedaudz sarežģītāku piemēru - metodi, kas savieno funkciju konkrētam kontekstam (I.E., objekts, uz kuru tas vārds tiks norādīts tajā).

Kods: funkcija.prototipe.bind \u003d funkcija (konteksts) (
var fn \u003d tas;
Atgriešanās funkcija () (
Atgriezties fn.Apply (konteksts, argumenti);
};
}
var hellopage \u003d (
Nosaukums: "Habrahabr",
init: funkcija () (
Brīdinājums ("hello", + šis.name);
}
}
//Window.onload \u003d hellopage.init; // Alertnul nenotiks, jo Tas norāda uz logu
logs.Onload \u003d hellopage.init.bind (hellopage); // Tagad viss darbojas

Šajā piemērā, izmantojot slēgšanu, funkcija, kas saistīta ar "Ohm, atceras sākotnējo funkciju un kontekstu, kas piešķirts tam.

Nākamais, būtiski atšķirīgs slēgšanas izmantojums - datu aizsardzība (Encapsulation). Apsveriet šādu dizainu:

Kods: (funkcija () () ()

})();

Acīmredzot slēgšanas iekšpusē mums ir piekļuve visiem ārējiem datiem, bet tam ir savs. Sakarā ar to mēs varam ieskauj daļu no koda, piemēram, dizains, lai aizvērtu vietējos mainīgos no piekļuves ārpuses. (Viens piemērs tās izmantošanas var redzēt avota kodu JQuery bibliotēkas, kas ieskauj visu tās koda slēgšanu, lai neizsauktu mainīgos lielumus tikai uz to).

Tomēr ir viens, kas saistīts ar šādu izmantošanas slazdu - vārda nozīme ir zaudēta slēgšanas iekšpusē. Tas tiek atrisināts šādi:

Kods: (funkcija () () ()
// augstākais tas turpināsies
)). Zvans (tas);

Apsveriet citu saņemšanu no tās pašas sērijas. To plaši populāra Yahoo UI sistēmas izstrādātāji, aicinot viņu par "moduļa modeli" un rakstot visu rakstu par to oficiālajā blogā.
Ļaujiet mums būt objektam (Singleton), kurā ir visas metodes un īpašības:

Kods: Var mymodule \u003d (
Nosaukums: "Habrahabr",
Saypreved: Funkcija (nosaukums) (
Brīdinājums ("leved" + name.Touppercase ())
},
this.SayPreved (šis.name);
}
}
Mymodule.sayprevedtohabrahabr ();

Ar aizvēršanas palīdzību mēs varam veikt metodes un īpašības, kas netiek izmantotas ārpus objekta, privātā (I.E. pieejams tikai viņam):

Kods: VAR MYMODule \u003d (funkcija () ()
VAR Vārds \u003d "Habrahabr";
Funkcija saypreved () (
Brīdinājums ("novērsis" + name.tuppercase ());
}
Atgriešanās (
Sayprevedtohabrahabr: funkcija () (
Saypreved (vārds);
}
}
})();
Mymodule.sayprevedtohabrahabr (); // brīdinājumi "novēroja Habruhabr"

Visbeidzot, es vēlos aprakstīt kopīgu kļūdu, ka daudzi brauc uz stuporu, ja nezināšana par to, kā slēgt darbu.

Ļaujiet mums būt virkne saites, un mūsu uzdevums ir padarīt to tā, ka, noklikšķinot uz katra allert, tiek parādīts tās secības numurs.
Pirmais lēmums, kas nāk prātā izskatās šādi:

Kods: par (var i \u003d 0; i< links.length; i++) {
Brīdinājums (i);
}
}

Faktiski izrādās, ka, noklikšķinot uz jebkuras saites, tiek parādīts tas pats numurs - saites vērtība.Length. Kāpēc tas notiek? Saistībā ar slēgšanu, paziņotais palīgamais mainīgais, kuru es turpinu pastāvēt, un tajā brīdī, kad mēs noklikšķinām uz saites. Tā kā līdz tam laikam cikls jau ir pagājis, es joprojām esmu vienāds ar saites skaitu - šī vērtība ir redzama, noklikšķinot uz.

Šī problēma tiek atrisināta šādi:

Kods: par (var i \u003d 0; i< links.length; i++) {
(Funkcija (i) (
Saites [i] .Oklick \u003d funkcija () (
Brīdinājums (i);
}
)) (I);
}

Šeit, izmantojot citu slēgšanu, mēs "ēnu" mainīgo I, radot to kopiju savā vietējā redzamības jomā katrā cikla solī. Pateicoties tam, viss darbojas tagad kā iecerēts.

Tas ir viss. Šis raksts, protams, nepieprasa būt izsmeļošs, bet kāds, es ceru, ka joprojām palīdz to izdomāt.

zy.
Lai saglabātu starp zvaniem vieglāk izmantot func_name.attr tips:

Kods: Funkciju skaits (atiestatīšana) (
ja (reset ||! collect.cnt) collect.cnt \u003d 0;
atgriezties countit.cnt ++;