„JavaScript“ uždarymo kilpose supratimas: praktiniai pavyzdžiai

„JavaScript“ uždarymo kilpose supratimas: praktiniai pavyzdžiai
„JavaScript“ uždarymo kilpose supratimas: praktiniai pavyzdžiai

Ciklo uždarymo atskleidimas JavaScript

JavaScript“ kūrėjai dažnai susiduria su netikėtu elgesiu, kai naudoja uždarymus kilpų viduje. Ši problema gali sukelti painiavą, ypač tiems, kuriems uždarymo sąvoka yra naujovė.

Šiame straipsnyje išnagrinėsime praktinius pavyzdžius, iliustruojančius dažniausiai pasitaikančias klaidas ir pateikiančius sprendimus, kaip efektyviai naudoti uždarymą kilpose, nesvarbu, ar tai susiję su įvykių klausytojais, asinchroniniu kodu ar kartojimu per masyvus.

komandą apibūdinimas
let Deklaruoja bloko apimties vietinį kintamąjį, pasirinktinai inicijuodamas jį į reikšmę. Naudojamas siekiant užtikrinti, kad kiekviena ciklo iteracija turėtų savo taikymo sritį.
const Deklaruoja bloko apimties, tik skaitoma pavadintą konstantą. Naudojamas norint sukurti funkciją arba kintamąjį, kurio reikšmė neturėtų keistis.
Promise Nurodo galutinį asinchroninės operacijos užbaigimą (arba gedimą) ir jos gaunamą reikšmę.
setTimeout Iškviečia funkciją arba įvertina išraišką po nurodyto milisekundžių skaičiaus.
addEventListener Prideda įvykių tvarkyklę prie nurodyto elemento neperrašant esamų įvykių tvarkyklių.
IIFE Iškart iškviesta funkcijos išraiška. Funkcija, kuri paleidžiama iš karto, kai tik yra apibrėžta. Naudojamas vietinėms apimtims kurti kilpose.
for...in Kartojama per nesuskaičiuojamas objekto savybes savavališka tvarka.
for...of Iteruoja per iteruojamo objekto (pvz., masyvo ar eilutės) reikšmes tam tikra tvarka.

„JavaScript“ uždarymo kilpose supratimas

Ankstesniuose pavyzdžiuose pateikti scenarijai sprendžia dažną „JavaScript“ kilpų uždarymo problemą. Kai naudojate a var ciklas, visos iteracijos turi tą pačią funkcijų apimtį. Štai kodėl pirmame pavyzdyje išvestis yra „Mano vertė: 3“ tris kartus. Sprendimas yra naudoti let, kuri sukuria bloko apimtį, kuri išlaiko teisingą kiekvienos iteracijos reikšmę. Šis metodas užtikrina, kad kiekviena iteracija turėtų savo apimtį, taip išsaugant teisingą reikšmę, kai funkcija iškviečiama. Scenarijus parodo, kaip pakeisti deklaraciją iš var į let ištaiso problemą ir registruoja „Mano vertė: 0“, „Mano vertė: 1“ ir „Mano vertė: 2“, kaip numatyta.

Asinchroninio kodo atveju gali kilti ta pati uždarymo problema. Naudojant Promises ir setTimeout funkcijos su let užtikrina, kad kiekvienas asinchroninis skambutis išlaikytų teisingą iteracijos reikšmę. Scenarijus parodo, kad naudojant wait su let, kiekvienas įvykdytas pažadas registruoja tikėtiną vertę. Renginių klausytojai taip pat gali susidurti su panašiomis problemomis; tačiau klausytojo funkciją įvyniojant į an IIFE (Iš karto iškviesta funkcijos išraiška) padeda užfiksuoti teisingą reikšmę, sukuriant naują kiekvienos iteracijos apimtį. Panaudojimas for...in ir for...of kilpos taip pat parodo, kaip svarbu nustatyti uždarymo sritį, ir parodo, kaip teisingai užfiksuoti indeksą ir vertę naudojant IIFE sukurti atskiras kiekvienos kilpos iteracijos sritis.

„JavaScript“ kilpų uždarymo problemų sprendimas naudojant „let“.

„JavaScript“ (ES6)

let funcs = [];
// Let's create 3 functions
for (let i = 0; i < 3; i++) {
  // and store them in funcs
  funcs[i] = function() {
    // each should log its value.
    console.log("My value:", i);
  };
}
for (let j = 0; j < 3; j++) {
  // and now let's run each one to see
  funcs[j]();
}

Teisingų uždarymo verčių užtikrinimas asinchroniniame kode

„JavaScript“ (ES6)

const wait = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms));
for (let i = 0; i < 3; i++) {
  // Log `i` as soon as each promise resolves.
  wait(i * 100).then(() => console.log(i));
}

Teisingas įvykių klausytojų uždarymas naudojant IIFE

„JavaScript“ (ES6)

var buttons = document.getElementsByTagName("button");
// Let's create 3 functions
for (var i = 0; i < buttons.length; i++) {
  // as event listeners
  (function(i) {
    buttons[i].addEventListener("click", function() {
      // each should log its value.
      console.log("My value:", i);
    });
  })(i);
}

Teisingas uždarymas su for...in and for... of Loops

„JavaScript“ (ES6)

const arr = [1, 2, 3];
const fns = [];
for (const i in arr) {
  fns.push(((i) => () => console.log("index:", i))(i));
}
for (const v of arr) {
  fns.push(((v) => () => console.log("value:", v))(v));
}
for (const n of arr) {
  const obj = { number: n };
  fns.push(((n, obj) => () => console.log("n:", n, "|", "obj:", JSON.stringify(obj)))(n, obj));
}
for (const f of fns) {
  f();
}

Uždarymo naudojimo išplėstinėse „JavaScript“ funkcijose tyrinėjimas

Uždarymai yra pagrindinė „JavaScript“ sąvoka, leidžianti funkcijai pasiekti kintamuosius iš savo aprėpties, net kai ši sritis uždaryta. Ši funkcija ypač efektyvi kuriant pažangias funkcijas, tokias kaip tas, kurios naudojamos įrašant atmintinę, pridedant ir naudojant funkcinį programavimą. Pavyzdžiui, atmintyje naudojamas uždarymas, kad atsimintų brangių funkcijų iškvietimų rezultatai ir būtų grąžintas talpykloje išsaugotas rezultatas, kai vėl kartojasi tie patys įėjimai. Naudodami uždarymus galime sukurti efektyvesnį ir optimizuotą kodą, kuris pagerina našumą, ypač rekursinėse funkcijose, pvz., Fibonačio sekų skaičiavime.

Kitas pažangus uždarymo naudojimas yra privačių kintamųjų ir funkcijų kūrimas „JavaScript“ objektuose, imituojant privačius metodus ir savybes. Ši technika dažnai naudojama modulių modeliuose ir iš karto iškviečiamose funkcijų išraiškose (IIFE), kad būtų galima įterpti funkcionalumą ir išvengti pasaulinės apimties užteršimo. Be to, uždarymai atlieka lemiamą vaidmenį tvarkant įvykius ir asinchroninį programavimą, kur jie padeda išlaikyti būseną ir kontekstą laikui bėgant. Supratimas ir efektyvus uždarymas gali žymiai pagerinti jūsų JavaScript programavimo įgūdžius ir sudaryti sąlygas rašyti moduliškesnį, daugkartinio naudojimo ir prižiūrimą kodą.

Dažnai užduodami klausimai apie „JavaScript“ uždarymą

  1. Kas yra „JavaScript“ uždarymas?
  2. Uždarymas yra funkcija, kuri išlaiko prieigą prie savo leksinės apimties, net kai funkcija vykdoma už jos ribų.
  3. Kodėl uždarymai vyksta kilpose?
  4. Ciklas užsidaro, nes ciklas sukuria funkcijas, kurios užfiksuoja tą pačią kintamojo nuorodą, todėl netinkamai tvarkoma netikėta elgsena.
  5. Kaip galime išspręsti kilpų uždarymo problemas?
  6. Naudojant let vietoj var kilpose arba naudojant IIFE (Iš karto iškviečiamos funkcijos išraiškos) gali išspręsti uždarymo problemas, sukurdami naują kiekvienos iteracijos taikymo sritį.
  7. Kas yra IIFE?
  8. An IIFE yra funkcija, kuri vykdoma iš karto po jos sukūrimo, dažnai naudojama kuriant naują sritį ir išvengti kintamųjų konfliktų.
  9. Ar asinchroniniame programavime gali būti naudojami uždarymai?
  10. Taip, uždarymai yra būtini asinchroniniam programavimui, kad būtų išlaikyta būsena ir kontekstas atliekant asinchronines operacijas, pvz., pažadus ir atgalinius skambučius.
  11. Kas yra atmintinė ir kaip padeda uždarymas?
  12. Atmintinė yra optimizavimo metodas, skirtas brangių funkcijų iškvietimų rezultatams išsaugoti talpykloje. Uždarymai padeda išlaikyti prieigą prie talpyklos kelių funkcijų skambučių metu.
  13. Kaip uždarymai padeda tvarkant įvykius?
  14. Uždarymai išlaiko įvykių tvarkytojams reikalingų kintamųjų būseną, užtikrinant, kad jie tinkamai veiktų, kai įvykis suaktyvinamas.
  15. Kas yra „JavaScript“ modulio šablonas?
  16. Modulio šablonas naudoja uždarymus, kad sukurtų privačius kintamuosius ir funkcijas, apimtų funkcionalumą ir išvengtų pasaulinės taršos.
  17. Ar uždarymai gali imituoti privačius metodus „JavaScript“?
  18. Taip, uždarymai gali imituoti privačius metodus, palikdami kintamuosius ir funkcijas pasiekiamus tik funkcijos apimtyje, kur jie yra apibrėžti.

Paskutinės mintys apie „JavaScript“ uždarymą kilpose

Norint rašyti nuspėjamą ir efektyvų kodą, labai svarbu įvaldyti „JavaScript“ uždarymus, ypač kilpose. Naudojant svertą let, Promises, ir IIFE, kūrėjai gali išvengti įprastų spąstų ir užtikrinti teisingą kintamo taikymo sritį. Šis supratimas pagerina gebėjimą valdyti asinchronines užduotis ir įvykiais pagrįstą programavimą, o tai galiausiai lemia patikimesnes programas.