Savladavanje strelice i ovih funkcija u JavaScriptu

  • Razumijevanje razlike između klasičnih funkcija, metoda i funkcija sa strelicama ključno je za kontrolu ponašanja funkcije `this` u JavaScriptu.
  • Funkcije strelica pružaju konciznu sintaksu i leksikon, idealne za povratne pozive i transformacije podataka bez stvaranja novog konteksta.
  • Tradicionalne funkcije su i dalje potrebne za konstruktore, metode s dinamičkim `this` i slučajeve gdje je potreban objekt arguments.
  • Odabir pravog tipa funkcije u svakoj situaciji poboljšava čitljivost, održivost i robusnost JavaScript koda.

Savladavanje funkcija strelica i "this" u JavaScriptu

Ako programirate u JavaScriptu, prije ili kasnije ćete naići na funkcije strelica i zloglasni `this` , i često uopće nije jasno šta se događa ispod. Između klasičnih funkcija, metoda, povratnih poziva i objekata, lako se zbuniti kontekstom i završiti otklanjajući grešaka u nečemu što satima izgleda "magično".

U sljedećim redovima, razotkrit ćemo svu tu "magiju" i vidjeti, smireno, ali direktno, kako funkcioniraju funkcije strelica, kako se razlikuju od regularnih funkcija i kakav je njihov stvarni odnos s `ovim` . Također ćemo pogledati ulogu metoda i funkcija općenito kako biste imali potpun pregled i mogli pisati moderan, čist i održiv kod.

Osnove: Šta je funkcija u JavaScriptu?

U JavaScriptu, funkcija je u suštini blok koda koji se može ponovo koristiti, definisan za izvršavanje određenog zadatka . Nakon što je deklarišete, možete je pozivati ​​onoliko puta koliko želite, sa različitim ulaznim vrijednostima, bez ponavljanja istog koda iznova i iznova.

Kada definirate klasičnu funkciju, koristite ključnu riječ ` function` , opcionalno ime i listu parametara u zagradama. Parametri predstavljaju ulaze, a povratna vrijednost predstavlja izlaz . Nešto tipično poput sabiranja dva broja izgleda ovako:

function suma(a, b) {
  return a + b;
}

let resultado = suma(5, 3);
console.log(resultado); // 8

U ovom dijelu koda, funkcija sum prima dva parametra, a i b , izvršava internu operaciju i vraća rezultat pomoću funkcije return , koju zatim možemo sačuvati u varijabli ili direktno koristiti.

Funkcije također mogu imati parametre sa zadanim vrijednostima , što je vrlo korisno za izbjegavanje grešaka kada kod poziva funkciju bez svih očekivanih argumenata:

function saludo(nombre = "desconocido") {
  return `¡Hola, ${nombre}!`;
}

console.log(saludo());      // ¡Hola, desconocido!
console.log(saludo("Alice")); // ¡Hola, Alice!

Zahvaljujući zadanim parametrima, vaša funkcija postaje robusnija i tolerantnija na nepotpune pozive , što vam štedi ručne provjere unutar tijela funkcije.

Pored sintakse, mudro korištenje funkcija donosi modularnost, mogućnost ponovne upotrebe i poboljšanu čitljivost : veliki problem se rastavlja na male, lako razumljive, lako testirane i održavajuće dijelove. Mnogo je jednostavnije testirati izoliranu funkciju nego ogroman blok koda pomiješan sa svime ostalim.

Normalne funkcije, metode i njihov kontekst

Prije nego što se udubimo u funkcije sa strelicama, korisno je razumjeti kako se tradicionalne funkcije ponašaju u odnosu na `this` kontekst i koja je razlika između "labavih" funkcija i metoda povezanih s objektima.

Regularna funkcija deklarirana sa `function` ima dinamičko ponašanje `this` : vrijednost `this` ovisi o tome kako se funkcija poziva, a ne gdje je napisana u kodu. Ako je pozovete kao samostalnu funkciju, `this` može pokazivati ​​na globalni objekt (u nestriktnom načinu rada) ili biti nedefinirano (u striktnom načinu rada). Ako je pozovete kao metodu objekta, `this` se obično odnosi na taj objekt.

Kada je ta funkcija dio objekta, obično je nazivamo metodom . Metoda je jednostavno funkcija pohranjena u svojstvu objekta. U tom kontekstu, `this` obično ukazuje na sam objekt kada pozivamo metodu koristeći tačkastu notaciju:

const persona = {
  nombre: "Laura",
  saludar: function () {
    console.log("Hola, soy " + this.nombre);
  }
};

persona.saludar(); // "Hola, soy Laura" (this => persona)

Ključna razlika između funkcije i metode nije tehničke prirode (obje su funkcije "ispod haube"), već gdje su pohranjene i kako se pozivaju . "Labave" funkcije se pozivaju po imenu, dok se metode pozivaju kroz objekt, a to direktno utiče na vrijednost `this`.

Osim toga, normalne funkcije se mogu koristiti kao konstruktori sa new , koji kreira instance objekata sa zajedničkim prototipom, a imaju i objekat arguments koji prikuplja sve proslijeđene argumente, čak i ako nisu eksplicitno definirani kao parametri.

Funkcije strelica: moderna sintaksa

Sa ECMAScript 6 (ES6) došle su i funkcije sa strelicama , koje nude mnogo koncizniji način pisanja funkcija, posebno kada su kratke ili se koriste kao povratne funkcije.

Najjednostavniji oblik streličaste funkcije zamjenjuje riječ function sa arrow => i u mnogim slučajevima omogućava implicitni povratak, također čuvajući povratak i vitičaste zagrade kada je tijelo funkcije jedan izraz:

const multiplicacion = (x, y) => x * y;

console.log(multiplicacion(4, 5)); // 20

Ove vrste funkcija se obično deklarišu kao izrazi pohranjeni u konstantama ili varijablama , jer su po svojoj prirodi anonimne (nemaju vlastito ime kao klasične deklarisane funkcije) i ne koriste se kao deklaracije funkcija s povišenim nivoima.

Opšta sintaksa se može sažeti na sljedeći način: parametri u zagradama, strelica =>, a zatim izraz ili blok koda . Ako imate samo jedan parametar, možete izostaviti zagrade; ako imate više parametara, oni su obavezni.

// Un solo parámetro, sin paréntesis
const doble = n => n * 2;

// Varios parámetros, paréntesis obligatorios
const sumar = (a, b) => a + b;

Kada logika više ne stane u jedan izraz i potrebno vam je nekoliko naredbi, koristite vitičaste zagrade i eksplicitni return , baš kao u tradicionalnoj funkciji:

const sumaCompleja = (a, b) => {
  let resultado = a + b;
  resultado = resultado * 2;
  return resultado;
};

Funkcije strelica također prihvataju parametre sa zadanim vrijednostima , što vam omogućava da definirate jasne početne vrijednosti bez potrebe za dodatnim internim provjerama:

const cuadrado = (lado = 10) => lado * lado;

console.log(cuadrado());   // 100
console.log(cuadrado(5));  // 25

Budući da funkcionišu kao izrazi, uobičajeno je da se nekoliko funkcija strelica pohrani u različite varijable za kasniju ponovnu upotrebu, na primjer:

const duplicar = n => n * 2;
const triplicar = n => n * 3;

console.log(duplicar(3));  // 6
console.log(triplicar(3)); // 9

Implicitni povratak i praktična sintaksa

Jedna od velikih prednosti streličnih funkcija je implicitni povratak kada se tijelo svodi na jedan izraz . Ovo čini vrlo uobičajene zadatke, poput transformiranja vrijednosti, izuzetno čistim:

const duplicar = n => n * 2;

Ovaj primjer je funkcionalno ekvivalentan pisanju normalne funkcije koja koristi return unutar bloka , ali štedi nekoliko riječi i linija koda:

const duplicar = function (n) {
  return n * 2;
};

Kada želite vratiti literalni objekt iz funkcije strelice s implicitnim povratom, morate staviti objekt u zagrade kako biste spriječili da se vitičaste zagrade interpretiraju kao početak bloka koda:

const obtenerUsuario = () => ({
  nombre: "Laura",
  edad: 28
});

S ovom sintaksom, streličke funkcije postaju idealni alati za pisanje kratkog i ekspresivnog koda , široko korištenog u metodama nizova, obećanjima, laganom funkcionalnom programiranju i komponentnoj logici u modernim okvirima.

Ovo u funkcijama strelica: leksički kontekst

Zaista važna razlika između streličke funkcije i klasične funkcije nije samo sintaksa: već način na koji obrađuju vrijednost `this` . Dok regularne funkcije imaju dinamičko `this` koje ovisi o njihovom imenu, streličke funkcije imaju leksički `this`.

Reći da je `ovo` leksički znači da funkcija strelice ne kreira vlastito interno `ovo` , već nasljeđuje `ovo` konteksta u kojem je definirana. Ako napišete strelicu unutar regularne funkcije, `ovo` strelice bit će isto kao i kod vanjske funkcije; ako ste u globalnom opsegu modula, ona nasljeđuje taj kontekst.

Ovo ima direktan uticaj kada koristite funkcije strelica kao metode objekta. Ako, na primjer, napišete nešto ovako:

const obj = {
  nombre: "Juan",
  imprimir: () => {
    console.log(this.nombre);
  }
};

obj.imprimir();

U ovom isječku koda, `this` unutar funkcije strelice se ne odnosi na `obj` , već na vanjski kontekst u kojem je ta strelica kreirana (na primjer, globalni objekt ili trenutni modul). Uobičajeni rezultat je da `name` nije definiran ili ne pokazuje na očekivanu vrijednost.

S druge strane, leksičko nasljeđivanje od `this` je blagoslov pri radu s povratnim pozivima unutar metoda . Umjesto pribjegavanja trikovima poput pohranjivanja `this` u međuvarijablu (`var that = this`) ili korištenja `.bind()`, strelica bez napora zadržava `this` iz roditeljskog konteksta:

function Contador() {
  this.valor = 0;

  setInterval(() => {
    this.valor++;
    console.log(this.valor);
  }, 1000);
}

new Contador();

U ovom primjeru, funkcija proslijeđena funkciji setInterval je strelica , tako da je ovo unutar nje i dalje instanca klase Counter, što znatno olakšava posao i izbjegava tipične kontekstualne greške.

Pored ovoga, funkcije strelica također ne kreiraju vlastitu verziju objekta arguments , tako da ako trebate pristupiti svim dinamički proslijeđenim argumentima, morat ćete koristiti operator rest (...params) ili pribjeći normalnoj funkciji, ovisno o slučaju.

Leksički opseg i zatvaranje pomoću funkcija strelica

Još jedna posljedica dizajna strelica je da dijele isti leksički opseg kao i njihov roditeljski kontekst . To je primjetno ne samo kod `this`, već i kod varijabli kojima mogu pristupiti, što se vrlo dobro uklapa u koncept closures (zatvorenih elemenata).

Zamislite funkciju koja vraća drugu unutrašnju funkciju. Ako je unutrašnja funkcija strelica, ona može nastaviti koristiti varijable definirane u vanjskoj funkciji , čak i nakon što je vanjska funkcija završila s izvršavanjem.

const exterior = () => {
  const variableExterna = "Valor exterior";

  return () => {
    console.log(variableExterna);
  };
};

const interna = exterior();
interna(); // "Valor exterior"

U ovom slučaju, interna funkcija je strelica koja koristi isti leksički opseg za nesmetan pristup eksternoj varijabli. Ovaj obrazac se široko koristi za kreiranje konfiguriranih funkcija, fabrika i enkapsulirane logike.

Funkcije strelica u odnosu na normalne funkcije: poređenje

Ako klasičnu funkciju i strelicu postavimo jednu pored druge, vidimo nekoliko relevantnih razlika koje utiču na to kako ih koristimo u svakodnevnoj praksi:

  • Sintaksa i konciznost: Normalna funkcija se zapisuje kao function nombre() {}, dok je strelica obično const nombre = () => {}U jednostavnim slučajevima, strelica je očito kraća i čitljivija.
  • Podizanje: tradicionalne deklaracije funkcija su elevanStoga ih možete pozvati prije njihove definicije u kodu. Strelice, koje su izrazi dodijeljeni varijablama ili konstantama, Ne mogu se koristiti prije nego što budu definirani.
  • Kontekst ovoga: Klasična funkcija ima dinamičko `this` koje se mijenja ovisno o tome kako se poziva; strelica ima leksički `this`, naslijeđen iz konteksta u kojem je deklarirana.
  • Koristite kao graditelj: Normalne funkcije se mogu pozvati sa novi za kreiranje objekata; funkcije strelica Ne mogu se koristiti kao građevinari.
  • Argumenti objekta: U tradicionalnim funkcijama imate argumenti; u strelicama ovaj objekat ne postoji i obično se koriste preostali parametri.

Zbog svih ovih razloga, najčešće se koriste streličaste funkcije za povratne pozive, brze transformacije podataka i logiku gdje vam nije potreban vlastiti `this` , a klasične funkcije se zadržavaju za konstruktore, metode objekata koje zahtijevaju dinamički `this` ili slučajeve kada vas zaista zanima objekt `arguments`.

Uobičajena upotreba funkcija strelica

U modernom JavaScriptu, svakodnevna upotreba je puna funkcija sa strelicama, posebno u povratnim pozivima, metodama nizova i funkcionalnom kodu . One su prirodna zamjena za tradicionalne anonimne funkcije.

Vrlo čest slučaj upotrebe je njihovo prosljeđivanje kao povratnih poziva u metodama niza kao što su forEach, map, filter ili reduce. Sintaksa postaje mnogo kraća, a nasljeđivanjem ovoga, bolje se uklapaju u mnoge scenarije:

const nombres = ;

nombres.forEach(nombre => {
  console.log(`Hola ${nombre}`);
});

U poređenju sa pisanjem iste stvari pomoću funkcije, verzija sa strelicom je mnogo čišća i ne gubi na čitljivosti:

.map(function (n) {
  return n * 2;
});

.map(n => n * 2);

Kada izvodite složenije transformacije, metode poput filter i map također očito imaju koristi od sintakse strelica:

const nums = ;

const pares = nums.filter(n => n % 2 === 0);
const duplicados = nums.map(n => n * 2);

console.log(pares);      // 
console.log(duplicados); // 

Strelice se također često koriste u povratnim pozivima tajmera ili događaja , pod uvjetom da rukovanje `this`-om koje pružaju odgovara vašim potrebama. U `setTimeout`-u, na primjer, vrlo je uobičajeno vidjeti:

setTimeout(() => {
  console.log("Mensaje con delay");
}, 1000);

Prilikom iteracije kroz nizove s funkcijama forEach i arrow , ova kombinacija je posebno pogodna za izvođenje jednostavnih operacija na svakom elementu bez gubitka jasnoće:

const nombres = ;

nombres.forEach(nombre => console.log("Hola " + nombre));

Kada je prikladno, a kada ne koristiti funkcije strelica?

S obzirom na sve navedeno, moglo bi se činiti da su streličaste funkcije rješenje za sve, ali stvarnost je da one nisu uvijek najbolji izbor . Postoje specifične situacije u kojima je poželjnije držati se tradicionalnih funkcija.

Streličke funkcije su odlične kada su vam potrebni kratki povratni pozivi, transformacije podataka, kompozicija funkcija i nasljeđivanje `this` iz okruženja . U tim slučajevima izbjegavate standardni kod, pojednostavljujete svoj kod i olakšavate praćenje logike vašeg programa.

Međutim, ne biste ih trebali koristiti kao konstruktore , jer ne rade direktno sa `new`. Ako vam je namjera kreirati prilagođene tipove, klase ili prototipove, nastavite koristiti regularne funkcije ili sintaksu `class`.

Također nije dobra ideja deklarirati metode objekta poput `strelica` ako očekujete da `ovo` pokazuje na taj objekt . Već smo vidjeli da `strelica` ne definira vlastito `ovo`, tako da vrijednost neće biti ono što mnogi programeri očekuju prilikom čitanja koda, što dovodi do suptilnih grešaka.

Čak i u stvarima poput nekih rukovatelja događajima ili API-ja koji svoje ponašanje zasnivaju na vrijednosti `this` , normalna funkcija može biti prikladnija, upravo zato što je tamo važno da se `this` mijenja ovisno o tome ko poziva funkciju.

Konačno, ako vam je potreban fleksibilan pristup svim argumentima primljenim putem arguments , možda će vam biti prirodnije koristiti tradicionalnu funkciju ili redizajnirati interfejs funkcije tako da koristi rest parametre.

Funkcije i metode u dizajnu JavaScript aplikacija

Kada shvatite razlike između funkcija sa strelicama, klasičnih funkcija i metoda , zaista ih možete iskoristiti za strukturiranje kompletnih JavaScript aplikacija, kako frontend tako i backend.

"Normalne" funkcije su odličan resurs za zadatke opšte namjene, kreiranje objekata (konstruktora) i logiku gdje želite preciznu kontrolu nad `this` . Njihove mogućnosti podizanja također mogu pojednostaviti organizaciju koda u velikim datotekama ako ih pažljivo rasporedite.

Metode, s druge strane, funkcioniraju kao specifične akcije povezane s podacima objekta . Savršeno je logično da se `this` odnosi na sam objekt, jer metode enkapsuliraju i ponašanje i stanje. Prilikom definiranja metode u prototipu ili klasi, prirodno je koristiti `function` ili skraćenu sintaksu za metode objekta.

Funkcije strelica dolaze u obzir kao komplementarni element: služe za povezivanje elemenata, transformaciju podataka i definiranje povratnih poziva bez vizualnog nereda . Njihova široka upotreba u modernim bibliotekama, okvirima i API-jima nije slučajnost: one se vrlo dobro uklapaju u deklarativni stil većeg dijela današnjeg koda.

Razumijevanje uloge svakog tipa funkcije, poznavanje kada koristiti jednu ili drugu funkciju i savladavanje ponašanja funkcije `this` omogućava vam da pišete robusniji, čistiji i skalabilniji JavaScript kod , izbjegavajući mnoge klasične zamke jezika.

Sve što smo vidjeli o klasičnim funkcijama, parametrima, metodama, funkcijama strelicama, leksičkom opsegu i posebnom rukovanju `this` već vam daje solidnu osnovu za rješavanje stvarnih projekata: od malih skripti do složenih aplikacija, odabir prave vrste funkcije za korištenje u svakom dijelu čini razliku između haotičnog koda i koda koji svatko može rado čitati, održavati i poboljšavati.

uredske skripte
Vezani članak:
Uvod u Office skripte za Excel Online

Dodaj kao preferirani izvor na Googleu