Sobes.tech
Middle

Kako zabraniti promenu konteksta u JavaScript-u?

sobes.tech АИ

Одговор од АИ

У Јаваскрипту, контекст извршавања функције (вредност this) се одређује динамички у тренутку позива. Потпуно забрањивање његове промене није могуће у апсолутном смислу, али се може контролисати или фиксирати контекст различитим методама:

  1. Методе call, apply, bind:

    • call и apply омогућавају позивање функције са јасно назначеним контекстом и аргументима (одвојено у call, као низ у apply).
    • bind креира нову везану функцију, у којој је this чврсто фиксиран на назначену вредност при креирању, без обзира на накнадни позив. Ово је најефикаснији начин да се "забрани" промена контекста за будуће позиве.
    // Пример са bind
    const obj = { вредност: 42 };
    function прикажиВредност() {
      console.log(this.вредност);
    }
    
    const везанаПрикажиВредност = прикажиВредност.bind(obj);
    
    везанаПрикажиВредност(); // Исписа 42
    везанаПрикажиВредност.call({ вредност: 100 }); // Ипак исписа 42, контекст је фиксиран
    
  2. Стрелне функције (Arrow Functions):

    • Стрелне функције немају свој this. Они захватају this из околине (лексичке области) у време дефинисања.
    • Контекст стрелне функције не може бити промењен помоћу call, apply, или bind.
    // Пример са стрелном функцијом
    const спољашњиОбјекат = { име: 'Спољашњи' };
    
    класа МојаКласа {
      constructor() {
        this.имеКласе = 'МојаКласа';
        this.прикажиИмеArrow = () => {
          // this овде захвата this из конструктора или области дефинисања МојаКласа
          console.log(this.имеКласе);
        };
      }
    
      прикажиИмеОбична() {
        // this овде се одређује при позиву
        console.log(this.имеКласе);
      }
    }
    
    const примерак = new МојаКласа();
    примерак.прикажиИмеArrow(); // Исписа 'МојаКласа'
    
    const другиОбјекат = { име: 'Други' };
    const везанаArrow = примерак.прикажиИмеArrow.bind(другиОбјекат); // Покушај промене контекста
    везанаArrow(); // Ипак исписа 'МојаКласа', контекст стрелне функције је неизменљив
    
    примерак.прикажиИмеОбична.call(другиОбјекат); // Исписа 'Други', контекст обичне функције се мења
    

Дакле, "забрана промене контекста" најбоље се схвата као чврсто фиксирање контекста. За то се користи bind за обичне функције и природно лексичко повезивање за стрелне функције. Стрелне функције у овом смислу су "непоколебивије".