JavaScript this cuvântul cheie este unul dintre cele mai dificile aspecte ale limbajului de înțeles. Dar este extrem de important pentru scrierea unui cod JavaScript mai avansat.

În JavaScript, fișierul this cuvântul cheie ne permite:

  • Reutilizați funcțiile în diferite contexte de execuție. Înseamnă că o funcție odată definită poate fi invocată pentru diferite obiecte folosind this cuvânt cheie.
  • Identificarea obiectului în contextul de execuție curent atunci când invocăm o metodă.

this cuvântul cheie este foarte strâns asociat cu funcțiile JavaScript. Cand vine vorba de this, fundamental este să înțelegem unde este invocată o funcție. Pentru că nu știm ce este în this cuvânt cheie până când funcția este invocată.

Utilizarea this pot fi clasificate în cinci diferite binding aspecte. În acest articol, vom învăța despre toate cele cinci aspecte cu exemple.

În primul rând, ce este obligatoriu?

În JavaScript, a Lexical Environment este locul unde este scris fizic codul dvs. În exemplul de mai jos, numele variabilei este lexically în interiorul funcției sayName().

ad-banner
function sayName() {
  let name="someName";
  console.log('The name is, ', name);
 }

Un Execution Context se referă la codul care se execută în prezent și la orice altceva care îl ajută să se execute. Pot exista o mulțime de medii lexicale disponibile, dar cel care este în prezent alergarea este gestionată de Contextul de execuție.

Cuvantul cheie JavaScript this 5 reguli de legare cheie
Mediul lexical vs Contextul de execuție

Fiecare din contextul de execuție conține un Environment Record. Pe măsură ce motorul JavaScript execută codul, variabilele și numele funcțiilor se adaugă la înregistrarea mediului.

Acest fenomen este cunoscut sub numele de Binding în JavaScript. Binding ajută la asocierea identificatorilor (variabile, nume de funcții) cu this cuvânt cheie pentru un execution context.

Nu vă faceți griji dacă vi se pare puțin greu de înțeles acum. Veți obține o înțelegere mai bună pe măsură ce vom continua.

Regula nr. 1: Cum funcționează legarea implicită JavaScript

Legarea implicită acoperă majoritatea cazurilor de utilizare pentru tratarea this cuvânt cheie.

În legarea implicită, trebuie să verificați ce conține la stânga operatorului punct (.) adiacent unei funcții la momentul invocării. Aceasta determină ce this este obligatoriu pentru.

Să vedem un exemplu pentru a-l înțelege mai bine.

let user = {
    name: 'Tapas',
    address: 'freecodecamp',
    getName: function() {
        console.log(this.name);
    }
};

user.getName();

Aici this este legat de obiectul utilizatorului. Știm acest lucru deoarece, în stânga operatorului punct (.) Adiacent funcției getName(), vedem user obiect. Asa de this.name va înregistra Tapas în consolă.

Să vedem un alt exemplu pentru a înțelege mai bine acest concept:

function decorateLogName(obj) {
      obj.logName = function() {
          console.log(this.name);
      }
  };

  let tom = {
      name: 'Tom',
      age: 7
  };

  let jerry = {
      name: 'jerry',
      age: 3
  };

  decorateLogName(tom);
  decorateLogName(jerry);

  tom.logName();
  jerry.logName();

În acest exemplu, avem două obiecte, tom și jerry. Am decorat (îmbunătățit) aceste obiecte atașând o metodă numită logName().

Observați că atunci când invocăm tom.logName(), tom obiectul este în stânga operatorului punct (.) adiacent funcției logName(). Asa de this este legat de tom obiect și înregistrează valoarea tom (this.name este egal cu Tom aici). Același lucru se aplică atunci când jerry.logName() este invocat.

Regula # 2: Cum funcționează legarea explicită JavaScript

Am văzut că JavaScript creează un mediu pentru a executa codul pe care îl scriem. Se ocupă de crearea memoriei pentru variabile, funcții, obiecte și așa mai departe în faza de creație. În cele din urmă execută codul în faza de execuție. Acest mediu special se numește Execution Context.

Pot exista multe astfel de medii (Contexturi de execuție) într-o aplicație JavaScript. Fiecare context de execuție funcționează independent de celelalte.

Dar uneori, este posibil să dorim să folosim lucruri dintr-un context de execuție în altul. Aici intervine legarea explicită.

În legarea explicită, putem apela o funcție cu un obiect atunci când funcția se află în afara contextului de execuție al obiectului.

Există trei metode foarte speciale, call(), apply() și bind() care ne ajută să realizăm legături explicite.

Cum JavaScript call() Metoda funcționează

Cu call() , contextul cu care trebuie apelată funcția va fi transmis ca parametru la call(). Să vedem cum funcționează cu un exemplu:

let getName = function() {
     console.log(this.name);
 }
 
let user = {
   name: 'Tapas',
   address: 'Freecodecamp'  
 };

getName.call(user);

Aici call() metoda este invocată pe o funcție numită getName(). getName() funcționează doar jurnale this.name. Dar ce este this aici? Acest lucru este determinat de ceea ce a fost transmis către call() metodă.

Aici, this se va lega de obiectul utilizator deoarece am trecut utilizatorul ca parametru la call() metodă. Asa de this.name ar trebui să înregistreze valoarea proprietății nume a obiectului utilizator, adică Tapas.

În exemplul de mai sus, am trecut doar un singur argument către call(). Dar putem transmite și mai multe argumente call(), asa:

let getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }

let user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

let hobbies = ['Swimming', 'Blogging'];
 
getName.call(user, hobbies[0], hobbies[1]);

Aici am transmis mai multe argumente către call() metodă. Primul argument trebuie să fie contextul obiectului cu care funcția trebuie invocată. Alți parametri ar putea fi doar valori de utilizat.

Aici trec Înot și Blogging ca doi parametri pentru getName() funcţie.

Ai observat un punct de durere aici? În cazul unui call(), argumentele trebuie transmise unul câte unul – ceea ce nu este un mod inteligent de a face lucrurile! Acolo este următoarea noastră metodă, apply(), vine în poză.

Cum JavaScript apply() Metoda funcționează

Acest mod agitat de a transmite argumente către call() metoda poate fi rezolvată printr-o altă metodă alternativă numită apply(). Este exact la fel ca call() dar vă permite să transmiteți argumentele mai convenabil. Uită-te:

let getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }
 
let user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

let hobbies = ['Swimming', 'Blogging'];
 
getName.apply(user, hobbies);

Aici putem transmite o serie de argumente, ceea ce este mult mai convenabil decât trecerea lor una câte una.

Sfat: când aveți doar un argument de valoare sau nu aveți argumente de valoare de transmis, utilizați call(). Când aveți mai multe argumente valorice de transmis, utilizați apply().

Cum JavaScript bind() Metoda funcționează

bind() metoda este similară cu call() metoda dar cu o singură diferență. spre deosebire de call() metoda de apelare directă a funcției, bind() returnează o funcție nouă și o putem invoca în schimb.

let getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }

let user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

let hobbies = ['Swimming', 'Blogging'];
let newFn = getName.bind(user, hobbies[0], hobbies[1]); 

newFn();

Aici getName.bind() nu invocă funcția getName() direct. Revine o funcție nouă, newFn și îl putem invoca ca newFn().

Regula # 3: JavaScript new Legare

A new cuvântul cheie este folosit pentru a crea un obiect din funcția constructor.

let Cartoon = function(name, character) {
     this.name = name;
     this.character = character;
     this.log = function() {
         console.log(this.name +  ' is a ' + this.character);
     }
 };

Puteți crea obiecte folosind new cuvânt cheie ca acesta:

 let tom = new Cartoon('Tom', 'Cat');
 let jerry = new Cartoon('Jerry', 'Mouse');

Când o funcție este invocată cu new cuvânt cheie, JavaScript creează un intern this obiect (cum ar fi, acesta = {}) în cadrul funcției. Nou creat this se leagă de obiectul creat cu ajutorul new cuvânt cheie.

Sună complex? Ok, hai să o descompunem. Ia această linie,

let tom = new Cartoon('Tom', 'Cat');

Aici funcția Cartoon este invocată cu new cuvânt cheie. Deci, creatul intern this va fi legat de noul obiect creat aici, adică tom.

Regula # 4: JavaScript Global Object Binding

Care credeți că va fi rezultatul codului de mai jos? Ce este this legat de aici?

let sayName = function(name) {
    console.log(this.name);
};

window.name="Tapas";
sayName();

Dacă this cuvântul cheie nu este rezolvat cu niciuna dintre legături, implicit, explicit sau new, apoi this este legat de window(global) obiect.

Există însă o excepție. JavaScript modul strict nu permite această legare implicită.

"use strict";
function myFunction() {
  return this;
}

În cazul de mai sus, this este undefined.

Regula # 5: Legarea elementului eveniment HTML în JavaScript

În gestionarele de evenimente HTML, this se leagă de elementele HTML care primesc evenimentul.

<button onclick="console.log(this)">Click Me!</button>

Este jurnalul de ieșire din consolă atunci când faceți clic pe butonul:

"<button onclick='console.log(this)'>Click Me!</button>"

Puteți schimba stilul butonului folosind this cuvânt cheie, ca acesta:

<button onclick="this.style.color="teal"">Click Me!</button>

Fiți atenți atunci când apelați o funcție pe butonul clic și utilizați this în interiorul acelei funcții.

<button onclick="changeColor()">Click Me!</button>

și JavaScript:

function changeColor() {
  this.style.color="teal";
}

Codul de mai sus nu va funcționa conform așteptărilor. Așa cum am văzut în regula 4, aici this va fi legat de obiectul global (în modul „non-strict”) unde nu există stil obiect pentru a seta culoarea.

În concluzie

A rezuma,

  • În cazul legării implicite, this se leagă de obiectul din stânga operatorului punct (.).
  • În cazul legării explicite, putem apela o funcție cu un obiect atunci când funcția se află în afara contextului de execuție al obiectului. Metodele call(), apply(), și bind() joacă un rol important aici.
  • Când o funcție este invocată cu new cuvânt cheie, this cuvântul cheie din interiorul funcției se leagă de noul obiect construit.
  • Cand this cuvântul cheie nu este rezolvat cu niciuna dintre legături, implicit, explicit sau new, atunci this este legat de window(global) obiect. În modul strict JavaScript, this va fi nedefinit.
  • În gestionarele de evenimente HTML, this se leagă de elementele HTML care primesc evenimentul.

Mai există un caz în care this se comportă diferit, cum ar fi cu ES6 arrow functions. Ne vom uita la asta într-un articol viitor.

Sper că ați găsit acest articol perspicace. Ați putea dori, de asemenea,

Dacă acest articol a fost util, vă rugăm să îl împărtășiți, astfel încât și alții să îl poată citi. Puteți să mă @ pe Twitter (@tapasadhikary) cu comentarii sau nu ezitați să mă urmați.