Разбиране на ключовата дума на JavaScript „това“.

Какво означава тази ключова дума в JavaScript? И как можете да го използвате практически във вашата JavaScript програма? Това са някои от често срещаните въпроси, които начинаещите и дори някои опитни разработчици на JavaScript задават относно тази ключова дума.

Ако сте един от онези разработчици, които се чудят какво представлява тази ключова дума, тогава тази статия е за вас. Проучете за какво се отнася това в различни контексти и се запознайте с някои проблеми, за да избегнете объркване и, разбира се, грешки във вашия код.

„това“ в глобалния обхват

В глобалния контекст това ще върне обекта прозорец, стига да е извън функция. Глобалният контекст означава, че не го поставяте във функция.

 if(true) {
  console.log(this)
}

let i = 2
while(i < 10) {
  console.log(this)
  i++
}

Ако изпълните горния код, ще получите обекта прозорец.

„това“ вътрешни функции (методи)

Когато се използва във функции, това се отнася до обекта, към който е обвързана функцията. Изключение е, когато използвате това в самостоятелна функция, в който случай връща обекта прозорец. Нека да видим някои примери.

В следващия пример функцията sayName е вътре в обекта me (т.е. това е метод). В случаи като този това се отнася до обекта, съдържащ функцията.

  
function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley",
  sayName: sayName
}

console.log(me.sayName())

това е обектът me, така че казването на this.name вътре в метода sayName е точно същото като me.name.

Друг начин да мислим за това е, че каквото и да е от лявата страна на функцията при извикване, ще бъде това. Това означава, че можете да използвате повторно функцията sayName в различни обекти и това ще препраща към напълно различен контекст всеки път.

  Как да създадете предварително зададено скриване на слайдове в PowerPoint

Сега, както споменахме по-рано, това връща обекта прозорец, когато се използва в самостоятелна функция. Това е така, защото самостоятелна функция е обвързана с прозореца по подразбиране:

 function talk() {
  return this
}

talk()

Извикването на talk() е същото като извикването на window.talk() и всичко, което е от лявата страна на функцията, автоматично ще стане това.

Като странична бележка тази ключова дума във функцията се държи по различен начин в стриктния режим на JavaScript (връща недефинирано). Това също е нещо, което трябва да имате предвид, когато използвате UI библиотеки, които използват строг режим (напр. React).

Използване на „това“ с Function.bind()

Възможно е да има сценарии, при които не можете просто да добавите функцията към обект като метод (както в последния раздел).

Може би обектът не е ваш и го изтегляте от библиотека. Обектът е неизменен, така че не можете просто да го промените. В случаи като този все още можете да изпълните оператора на функцията отделно от обекта, като използвате метода Function.bind().

В следния пример функцията sayName не е метод на обекта me, но все пак сте я обвързали с помощта на функцията bind():

 function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley"
}

const meTalk = sayName.bind(me)

meTalk()

Какъвто и обект да подадете в bind(), ще бъде използван като стойност на this в това извикване на функция.

В обобщение, можете да използвате bind() за всяка функция и да преминете в нов контекст (обект). И този обект ще презапише значението на това вътре в тази функция.

  7 професионални SQL сертификати за тласък на вашата кариера през 2022 г

Използване на „това“ с Function.call()

Какво става, ако не искате да върнете изцяло нова функция, а просто да извикате функцията, след като я свържете с нейния контекст? Решението за това е методът call():

 function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley"
}

sayName.call(me)

Методът call() незабавно изпълнява функцията, вместо да връща друга функция.

Ако функцията изисква параметър, можете да го предадете чрез метода call(). В следващия пример вие предавате езика на функцията sayName(), така че можете да я използвате, за да връщате условно различни съобщения:

 function sayName(lang) {
  if (lang === "en") {
    return `My name is ${this.name}`
  } else if (lang === "it") {
    return `Io sono ${this.name}`
  }
}

const me = {
  name: "Kingsley"
}

sayName.call(me, 'en')
sayName.call(me, 'it')

Както можете да видите, можете просто да предадете всеки параметър, който искате, на функцията като втори аргумент на метода call(). Можете също така да подадете толкова параметри, колкото искате.

Методът apply() е много подобен на call() и bind(). Единствената разлика е, че предавате множество аргументи, като ги разделяте със запетая с call(), докато предавате множество аргументи в масив с apply().

В обобщение, bind(), call() и apply() ви позволяват да извиквате функции с напълно различен обект, без да имате каквато и да е връзка между двете (т.е. функцията не е метод на обекта).

„това“ Вътрешни функции на конструктора

Ако извикате функция с нова ключова дума, тя създава този обект и го връща:

 function person(name){
  this.name = name
}

const me = new person("Kingsley")
const her = new person("Sarah")
const him = new person("Jake")

me.name
her.name
him.name

В горния код създадохте три различни обекта от една и съща функция. Ключовата дума new автоматично създава обвързване между обекта, който се създава, и ключовата дума this във функцията.

  Как да използвате нощното виждане на охранителната камера през прозорец

„това“ Вътрешни функции за обратно извикване

Функциите за обратно извикване са различни от обикновените функции. Функциите за обратно извикване са функции, които предавате на друга функция като аргумент, така че те могат да бъдат изпълнени веднага след като основната приключи изпълнението.

Тази ключова дума се отнася до напълно различен контекст, когато се използва във функции за обратно извикване:

 function person(name){
  this.name = name
  setTimeout(function() {
    console.log(this)
  }, 1000)
}

const me = new person("Kingsley")

След една секунда на извикване на функцията конструктор person и създаване на нов обект me, тя ще регистрира обекта прозорец като стойност на this. Така че, когато се използва във функция за обратно извикване, това се отнася до прозореца, а не до „конструирания“ обект.

Има два начина да поправите това. Първият метод използва bind() за обвързване на функцията person към новосъздадения обект:

 function person(name){
  this.name = name
  setTimeout(function() {
    console.log(this)
  }.bind(this), 1000)
}

const me = new person("Kingsley")

С горната модификация this в обратното извикване ще сочи към същото this като функцията конструктор (обектът me).

Вторият начин за решаване на проблема с това във функциите за обратно извикване е чрез използване на функции със стрелки.

„това“ Вътрешни функции със стрелки

Функциите със стрелки са различни от обикновените функции. Можете да направите функцията за обратно извикване функция със стрелка. С функциите със стрелки вече не се нуждаете от bind(), защото той автоматично се свързва с новосъздадения обект:

 function person(name){
  this.name = name
  setTimeout(() => {
    console.log(this)
  }, 1000)
}

const me = new person("Kingsley")

Научете повече за JavaScript

Научихте всичко за ключовата дума „this“ и какво означава тя във всички различни контексти в JavaScript. Ако не сте запознати с JavaScript, ще ви е много полезно да научите всички основи на JavaScript и как работи.