Галоўная > Што такое this? У які момант ствараецца? Ад чаго залежыць кантэкст? Як яго згубіць, чаму губляецца this і як яго знайсці зноў.

Што такое this? У які момант ствараецца? Ад чаго залежыць кантэкст? Як яго згубіць, чаму губляецца this і як яго знайсці зноў.

сумоўе
js
beginner

this - кантэкст выконвання функцыі. Іншымі словамі - гэта аб'ект, які дадаецца дынамічна ў момант выкліка функцыі і адлюстроўвае той аб'ект, які выклікаў гэтую функцыю. То бок мы можам выклікаць нашу функцыю з рознымі аб'ектамі, і кантэкст будзе змяняцца ў залежнасці ад таго, з якім аб'ектам выкліканая функцыя.

Спосабы выклікання функцыі:

  1. Звычайны выклік функцыі
  2. Функцыя, як метад аб'екта
  3. Як callback для метадаў масіва (filter, map і іншых)
  4. Стрэлачная функцыя
  5. З дапамогай call, apply, bind
  6. Як канструктар

1. Звычайны выклік

Адказ залежыць ад "use strict". Калі ён уключаны, this для глабальнай вобласці будзе undefined. Калі ражым не строгі, this = window.

function printThis() {
  console.log(this);
}

2. Функцыя, як метад аб'екта

// Маем 2 аб'екта - user і admin і функцыю showRole.
const user = {
  role: 'user',
};

const admin = {
  role: 'admin',
};

function showRole() {
  console.log(this.role);
}

// Дадаем у аб'екты метады showRole
user.showRole = showRole;
admin.showRole = showRole;

user.showRole(); // user

admin.showRole(); // admin

Як зразумець, з якім кантэкстам будзе выкліканая функцыя? Трэба паглядзець, што знаходзіцца перад кропкай у момант выкліку функцыі. Гэта і будзе кантэкст.

3. Як callback для метадаў масіва (filter, map і іншых)

cb у метадаў масіву, такіх як map, filter, forEach і іншых, губляе кантэкст, як і ў многіх іншых выпадках ( разглядзім пазней). Калі патрэбна перадаць для cb кантэкст, то ёсць 2 магчымасці для гэтага:

  • Метады масіва акрамя cb прымаюць другі неабавязковы аргумент - кантэкст
[1, 2, 3].map(cb, this);
  • Можна скарыстацца bind
[1, 2, 3].map(cb.bind(this));

4. Стрэлачная функцыя

У arrow funtion свайго this няма. Ён возьмецца са знешняга асяроддзя. Тут падрабязней.

5. З дапамогай call, apply, bind

call і apply дазваляюць адразу выклікаць функцыю з патрэбным кантэкстам. Для call можна дадаткова перадаць аргументы праз коску, для apply - масіў аргументаў.

bind прывязвае кантэкст да функцыі (змяніць ужо нельга), якую можна выклікаць пазней. Тут можна разгледзець падрабязей.

6. Як канструктар

Для канструктара пры выкліку з new ствараецца новы аб'ект, ён прысвойваецца this, дадаюцца ўласцівасці і метады з канструктара, калі няма return (а звычайна мы яго не пішам), з функцыі-канструктара вяртаецца this з захованымі ўласцівасцямі. Тут можна разгледзець падрабязей.

Калі можна згубіць this?

Калі каротка - то любая аперацыя з метадам аб'екта, акрамя яго непасрэднага выкліка, прыводзіць да страты кантэксту.

Вось так добра:

let user = {
  name: "Хведар",
  hi: function() { console.log('Вітаначкі, ', this.name); },
  bye: function() { console.log("Да сустрэчы, ", this.name); }
};

user.hi();
user.by();

Вось так - не (губляем this):

This мае дынамічную вобласць бачнасці, таму кантэкст возьмецца з места выкліка

let user = {
  name: "Хведар",
  hi: function() { console.log('Вітаначкі, ', this.name); },
  bye: function() { console.log("Да сустрэчы, ", this.name); }
};

// 1
const hi = user.hi;
hi(); // няма аб'екта перад кропкай - кантэкст згубілі. Ён возьмецца з глабальнай вобласці бачнасці.

// 2
(user.name === "Хведар" ? user.hi : user.bye)(); 
// у нас атрымліваецца  (function)() - спачатку выбралі функцыю, а потым толькі выклікалі. 
// І зноў няма аб'екта перад кропкай.

// 3

setTimeout(user.hi, 100);

Спіс можна працягваць і далей, але, думаю, што прынцып зразумелы.

Чаму адбываецца страта this?

Калі мы выклікаем функцыю як метад - user.hi() - JavaScript стварае спецыяльны ўнутраны аб'ект Reference Type. Мы да яго доступа не маем. Ён патрэбны, каб перадаць інфармацыю ад кропкі. да выклікаючых функцыю дужак (). З гэтага аб'екта JavaScript і возьме кантэкст.

Reference Type мае 3 уласцівасці:

  • base - сам аб'ект
  • name - імя ўласцівасці аб'екта
  • strict - ражым выконвання. Калі ўключаны строгі ражым, мае значэнне true

Пры любой іншай аперацыі, акрамя непасрэднага выкліка функцыі як метада, Reference Type губляецца (замяняецца на саму функцыю user.hi). Таму звярнуцца да нашага аб'екта мы ўжо не зможам.

Што рабіць:

  1. Перш за ўсё памятаць пра асаблівасць this у JavaScript.
  2. Для setTimeout можна выкарыстоўваць функцыі-абгорткі
setTimeout(() => user.sayHi(), 1000);

Але трэба улічваць, што за час таймера user можа змяніцца і мы ўбачым зусім не тое, на што разлічвалі.

3.Выкарыстоўваць bind, call, apply

loveJS, 2023-06-18
Каментары

    (Каб даслаць каментар залагуйцеся ў свой уліковы запіс)

    ;