Sobes.tech
Middle

Kaip uždrausti konteksto keitimą JavaScript?

sobes.tech AI

Atsakymas iš AI

JavaScript kontekstas funkcijos vykdymo (reikšmė this) nustatomas dinamiškai iškvietimo metu. Jo pakeisti visiškai neįmanoma absoliučiuoju prasme, tačiau jį galima kontroliuoti arba fiksuoti įvairiais būdais:

  1. call, apply, bind metodai:

    • call ir apply leidžia iškviesti funkciją su aiškiai nurodytu kontekstu ir argumentais (atskirtai call, masyvu apply).
    • bind sukuria naują susietą funkciją, kurioje this griežtai fiksuotas nurodytai reikšmei kuriant, nepriklausomai nuo vėlesnio iškvietimo. Tai yra efektyviausias būdas "uždrausti" konteksto keitimą būsimuose iškvietimuose.
    // Pavyzdys su bind
    const obj = { reikšmė: 42 };
    function parodytiReikšmę() {
      console.log(this.reikšmė);
    }
    
    const susietaParodytiReikšmę = parodytiReikšmę.bind(obj);
    
    susietaParodytiReikšmę(); // Išves 42
    susietaParodytiReikšmę.call({ reikšmė: 100 }); // Vis tiek išves 42, kontekstas fiksuotas
    
  2. Rodyklės funkcijos (Arrow Functions):

    • Rodyklės funkcijos neturi savo this. Jos paima this iš aplinkos (leksinės srities) savo apibrėžimo metu.
    • Rodyklės funkcijos kontekstas negali būti pakeistas naudojant call, apply ar bind.
    // Pavyzdys su rodyklės funkcija
    const išorinisObjektas = { pavadinimas: 'Išorinis' };
    
    klasė ManoKlasė {
      constructor() {
        this.klasėsPavadinimas = 'ManoKlasė';
        this.parodytiPavadinimąRodyklė = () => {
          // čia `this` paima iš konstruktoriaus arba apibrėžimo aplinkos
          console.log(this.klasėsPavadinimas);
        };
      }
    
      parodytiPavadinimąĮprasta() {
        // čia `this` nustatomas iškvietimo metu
        console.log(this.klasėsPavadinimas);
      }
    }
    
    const pavyzdys = new ManoKlasė();
    pavyzdys.parodytiPavadinimąRodyklė(); // Išves 'ManoKlasė'
    
    const kitasObjektas = { pavadinimas: 'Kitas' };
    const susietaRodyklė = pavyzdys.parodytiPavadinimąRodyklė.bind(kitasObjektas); // Bandymas pakeisti kontekstą
    susietaRodyklė(); // Vis tiek išves 'ManoKlasė', rodyklės funkcijos kontekstas nekeičiama
    
    pavyzdys.parodytiPavadinimąĮprasta.call(kitasObjektas); // Išves 'Kitas', įprastos funkcijos kontekstas keičiasi
    

Taigi, "konteksto pakeitimo draudimas" geriausiai suprantamas kaip griežtas konteksto fiksavimas. Tam naudojamas bind įprastoms funkcijoms ir natūralus leksinis susiejimas rodyklės funkcijoms. Rodyklės funkcijos šiame požiūryje yra "nepažeidžiamos".