Funkce šipek JavaScriptu – přátelský úvod

V tomto článku se dozvíte o funkcích šipek, syntaxi, parametrech, závorkách a složených závorkách a o tom, kdy je můžete vynechat. Dozvíte se také o implicitním a explicitním návratu, okamžitě vyvolaných funkcích šipek a hlavních rozdílech mezi funkcemi a funkcemi šipek.

Úvod

Funkce šipek byly jednou z nejpozoruhodnějších funkcí JavaScriptu, které byly přidány se specifikací ES6. Byly také jednou z nejdiskutovanějších funkcí v ES6 spolu s třídami. Pojďme se tedy podívat, co jsou funkce šipek, jak fungují a jak je používat.

Syntaxe funkcí šipek

Nejpozoruhodnější charakteristikou funkce šipky je „fat arrow“ (=> ). Také díky této „tlusté šipce“ dostaly funkce šipky svůj název a také přezdívku „tučné šipky“. Tato „tučná šipka“ stojí mezi závorkami pro parametry, které spouštějí funkci šipky, a tělem funkce s nějakým kódem k provedení, který funkci šipky ukončí.

// Arrow function syntax
let myArrowFunc = () => // concise function body with some code

// Or
let myArrowFunc = () => {/* block function body with some code */}

// Call myArrowFunc
myArrowFunc()

Pokud porovnáte syntaxi funkcí šipek s funkcemi, uvidíte, že syntaxe těchto dvou je velmi podobná. Právě z tohoto důvodu jsou funkce šipek považovány za alternativu k výrazu funkce.

// Arrow function
const myArrowFunc = () => {/* function body with some code */}

// Function expression
const myArrowFunc = function() {}

To znamená, nenechte se touto podobností zmást. Přestože funkce šipek mohou vypadat podobně jako funkce, existují některé významné a velmi důležité rozdíly. O všech těchto rozdílech si brzy promluvíme.

Parametry a (volitelné) závorky

Funkce šipek obvykle začínají závorkami. To však není zcela nutné. Tyto závorky jsou volitelné a můžete je vynechat za jedné konkrétní podmínky. Jediné, na čem záleží, je, jestli konkrétní funkce šipky přijímá nějaký parametr. Pokud žádné nepřijímá, musíte použít prázdné závorky (() ).

Totéž platí pro funkce šipek, které přijímají dva nebo více parametrů. V tomto případě musíte tyto parametry uzavřít do závorek (() ). A také se ujistěte, že každý parametr oddělujete čárkou. Nyní nám zbývá jeden možný scénář, kde jsou závorky volitelné.

Když funkce šipky přijímá pouze jeden parametr. Potom můžete buď použít nebo vynechat závorky. Pamatujte, že pokud rádi používáte závorky, nic vám v tom nebrání. Závorky můžete používat neustále, bez ohledu na to, kolik parametrů je, a funkce šipek budou fungovat. Jinak si pamatujte pravidlo jedna.

// Arrow function with 0 parameters
// Parentheses are required here
const myArrowFunc = () => // some code


// Arrow function with 1 parameter
// Parentheses are optional here
const myArrowFunc = paramOne => // some code

// This will also work
const myArrowFunc = (paramOne) => // some code

const myArrowFunc = (paramOne) => console.log(paramOne)

// Call myArrowFunc
myArrowFunc('Something')


// Arrow function with 2+ parameters
// Parentheses are required here
const myArrowFunc = (paramOne, paramTwo) => // some code

const myArrowFunc = (paramOne, paramTwo) => paramOne + paramTwo

// Call myArrowFunc
myArrowFunc(13, 46)
// 59

Volitelné složené závorky

Další věcí, která je v případě funkcí šipek volitelná, jsou složené závorky. Zde je podmínka ještě jednodušší, než tomu bylo v případě závorek. Jedna věc, na které záleží, je, zda je funkce šipky jednořádková nebo ne. Pokud je funkce šipky jednořádková, můžete vynechat složené závorky a tato funkce bude stále fungovat podle očekávání.

V opačném případě, pokud tělo funkce obsahuje kód, který zahrnuje více než jeden řádek, jsou vyžadovány složené závorky a musíte je použít. Funkce šipky bez složených závorek se nazývá funkce šipky s „výstižným tělem“. Funkce šipky se složenými závorkami se nazývá funkce šipky s „tělem bloku“.

Stejně jako u závorek, pokud rádi používáte složené závorky, můžete je používat stále a bude to fungovat. Pokud je chcete vynechat, pamatujte, že je to bezpečné pouze v případě funkcí jednořádkových šipek.

// One-line arrow function
// Arrow function with concise body
// Curly brackets are optional here
const myArrowFunc = () => // some code
const myArrowFunc = () => console.log('Hello!')

// This will also work
() => {/* some code */}

const myArrowFunc = () => {/* some code */}
const myArrowFunc = () => { console.log('Hello!') }

// Call myArrowFunc
myArrowFunc()
// Hello!


// Multi-line arrow function
// Arrow function with block body
// Curly brackets are required here
const myArrowFunc = () => {
  // some code
}

const myArrowFunc = () => {
  console.log('This is a multi-line arrow function.')
}

// Call myArrowFunc
myArrowFunc()
// 'This is a multi-line arrow function.'

Když se nad tím zamyslíte, dává to smysl. V případě jednoho řádku je pro JavaScript snadné uhodnout, kde těla funkcí šipek začínají a kde končí. To není případ těla funkce, které se rozprostírá přes více řádků. V tomto případě JavaScript netuší, kde jsou hranice těla funkce.

Pamatujte, že JavaScript se nestará o mezery a odsazení. V Pythonu můžete například určit, kde začíná a končí tělo funkce odsazením tohoto bloku kódu. V JavaScriptu to nebude fungovat. V JavaScriptu můžete svůj kód odsadit, jak chcete, a JavaScript se stejně usměje a bude ho ignorovat.

// This will not work - omitting curly brackets
// Arrow function with concise body
// in multi-line arrow functions
() =>
  // some code

const myArrowFunc = () =>
  // some code

Implicitní a explicitní návrat

Jedna zajímavá věc na funkcích šipek je, že mají implicitní návrat. To znamená, že funkce šipek vracejí hodnoty automaticky. Nemusíte používat return klíčové slovo. To znamená, že to funguje ve dvou konkrétních situacích. První je, když je funkce šipky jednořádková.

Pokud se jedná o jednořádkovou šipku, funkce automaticky vrátí jakýkoli kód v těle funkce. Pokud funkce šipky není jednořádková, musíte použít return prohlášení.

// One-line arrow function
// Explicit return statement is not needed
() => // some code
const myArrowFunc = () => // some code

// Call myArrowFunc
myArrowFunc()


// Multi-line arrow function
// Explicit return statement is necessary
() => {
  return /* some code */
}
const myArrowFunc = () => {
  return /* some code */
}

// Call myArrowFunc
myArrowFunc()

Druhá situace, kdy musíte použít return příkaz je, když funkce šipky používá tělo bloku, tj. tělo funkce se složenými závorkami. To je další věc, kterou musíte vzít v úvahu při rozhodování, jakou syntaxi chcete použít. Ať už chcete použít „blokové tělo“ a složenou závorku nebo „stručné tělo“ bez složené závorky.

Pokud se jedná o pozdější, stručné tělo, nemusíte používat explicitní return tvrzení. Pokud první, tělo bloku, ujistěte se, že používáte return prohlášení.

// Arrow function with concise body
// Explicit return statement is not needed
() => // some code (this is concise body)
const myArrowFunc = () => // some code (this is concise body)

// Call myArrowFunc
myArrowFunc()


// Arrow function with block body
// Explicit return statement is necessary
() => {/* some code (this is block body) */}
const myArrowFunc = () => {/* some code (this is block body) */}

// Call myArrowFunc
myArrowFunc()

Okamžitě vyvolané funkce šipky

Jedna věc, kterou vám JavaScript umožňuje, je deklarovat a vyvolávat funkce současně. Tyto funkce se nazývají okamžitě vyvolané funkce. Jedním ze způsobů, jak vytvořit tento typ funkce, je zabalit funkci do závorek a přidat další pár závorek za závorky.

Druhý způsob je také o zabalení funkce do závorek a přidání další dvojice závorek za složené závorky, stále uvnitř závorek. Třetí způsob je o vynechání zalamovacích závorek a vložení operátoru NOT (! ) na začátku řádku, před function klíčové slovo.

Čtvrtý způsob je podobný předchozímu s tím rozdílem, že operátor NOT nahradíte unárním operátorem + .

// Immediately invoked function no.1:
// invoking parentheses outside wrapping parentheses
(function() {
  // some code
})()


// Immediately invoked function no.2:
// invoking parentheses inside wrapping parentheses
(function() {
  // some code
}())


// Immediately invoked function no.3:
// using ! (NOT operator)
!function() {
  // some code
}()


// Immediately invoked function no.4:
// Using + (unary operator)
+function() {
  // some code
}()

Totéž můžete udělat také s funkcemi šipek, vytvořit okamžitě vyvolané funkce šipek. Důležité je, že v případě funkcí šipek můžete použít pouze první způsob. Další tři selžou. Takže zabalte funkci šipky do závorek a přidejte další pár závorek za závorky.

// Immediately invoked one-line arrow function
// This will work
// Wrap arrow function with parentheses
// add additional set of parentheses
// outside the wrapping parentheses
(() => /* some code */)()


// Immediately invoked multi-line arrow function
// This will work
(() => {
  /* some code */
})()


// This will not work
(() => {
  // some code
}())

// This will also not work
!() => {
  // some code
}()

// This will also not work
+() => {
  // some code
  return 'foo'
}()

Pamatujte, že všechna pravidla o nepovinných závorkách a složených závorkách stále platí. To znamená, že pokud funkce šipky nemá žádné nebo dva parametry nebo parametry, musíte vložit závorky. Pokud je víceřádkový, musíte použít složené závorky a return tvrzení. Pokud je jednořádkový, ale používá tělo bloku, musíte také použít return prohlášení.

// Concise body with implicit return
(() => /* some code */)()

// Block body with explicit return
(() => { return /* some code */ })()

// Or
(() => {
  return /* some code */
})()

Rozdíly mezi funkcemi šipek a funkcemi

Funkce šipek a funkce jsou podobné. Jsou zde však minimálně dva důležité rozdíly. Podívejme se na každý z těchto rozdílů. To vám pomůže rozhodnout, kdy je lepší používat funkce šipek a kdy funkce.

Žádný objekt argumentů

Při práci s funkcemi máte vždy přístup k objektu arguments. Tento objekt obsahuje všechny hodnoty, které byly předány funkci při jejím vyvolání. V případě funkcí šipek takový objekt neexistuje. I když předáte nějaké argumenty funkcím šipek, JavaScript při pokusu o přístup k arguments stále vyvolá chybu odkazu objekt.

// Function
const myFunction = function(param) {
  return arguments
}

myFunction('Something')
// { '0': 'Something' }


// Arrow function
const myArrowFunction = (param) => arguments

myArrowFunction('Something')
// ReferenceError: arguments is not defined

Takže nezapomeňte, pokud plánujete použít arguments objektová běžná funkce je lepší volbou než funkce šipky.

Toto není závazné

Další věc, která ve funkcích šipek chybí, je this . Když pracujete s funkcemi, pokaždé, když definujete funkci, vytvoří také svou vlastní this . Pokud nepoužíváte přísný režim this bude odkazovat na globální window objekt. Pokud používáte přísný režim, hodnota this bude nedefinováno.

Když použijete funkci k vytvoření konstruktoru funkcí this bude nový objekt. Pokud použijete funkci jako objekt nebo třídu, použijte metodu this bude odkazovat na nadřazený objekt nebo třídu této funkce.

// This in non-strict mode
function myFunction() {
  console.log(this, this === window)
}

myFunction()
// [object Window], true


///
// This in strict mode
'use strict'

function myFunction() {
  console.log(this, this === window)
}

myFunction()
// undefined, false


// Function inside an object
const myObj = {
  title: 'Atlas Shrugged',
  author: 'Ayn Rand',
  getBook: function() {
    // This refers to myObj
    // So, this.title is like myObj.title
    return `${this.title} by ${this.author}.`
  }
}

myObj.getBook()
// 'Atlas Shrugged by Ayn Rand.'

V případě funkcí šipek je situace jiná. Funkce šipek nemají vlastní this . Funkce šipek dědí this z kontextu provádění, ve kterém jsou použity. Když jste ve výchozím globálním prostředí, kontext provádění je také globální, obvykle window objekt.

// This in non-strict mode
// Arrow function
let myArrowFunction = () => {
  console.log(this, this === window)
}

myArrowFunction()
// [object Window], true


///
// This in strict mode
'use strict'

let myArrowFunction = () => {
  console.log(this, this === window)
}

myArrowFunction()
// [object Window], true

Když jste ve funkci, kontext provádění se stane funkcí. S funkcemi šipek není pro this žádná vazba . Místo toho this je zděděno z původního kontextu. Pokud existuje pouze objekt, kontext provádění bude globální, window objekt. To je problém.

Představte si, že máte uvnitř objektu funkci šipky. Když použijete this uvnitř této funkce šipky bude odkazovat na globální kontext provádění, window , nikoli objekt, ve kterém se nachází. To znamená, že potom nemůžete použít this když chcete odkazovat na nějakou vlastnost uvnitř tohoto objektu.

Pamatujte, this nyní odkazuje na window a window tuto vlastnost nemá. Pokud to tedy zkusíte, JavaScript vyvolá chybu typu. Řešení? Místo toho použijte běžnou funkci.

// Arrow function inside an object
const myObj = {
  title: 'Atlas Shrugged',
  author: 'Ayn Rand',
  getBook: () => {
    // This refers to global object window
    // So, this.title is like window.title
    return `${this.title} by ${this.author}.`
  },
  getBookWithRegularFunction: function() {
    // This refers to myObj
    // So, this.title is like myObj.title
    return `${this.title} by ${this.author}.`
  }
}

myObj.getBook()
// TypeError: Cannot read property 'title' of undefined

myObj.getBookWithRegularFunction()
// 'Atlas Shrugged by Ayn Rand.'

To je jeden z důvodů, proč funkce šipek nejsou nejlepší volbou pro objektové metody. Také je, že funkce šipek nelze použít jako konstruktory. Pokud se o to pokusíte, JavaScript vyvolá chybu typu.

Závěr:Funkce šipek JavaScriptu

Doufáme, že vám tento článek pomohl dozvědět se o funkcích šipek JavaScriptu, jak fungují a jak je používat. V rekapitulaci jste se dnes dozvěděli o základních funkcích šipek a syntaxi. Dále jste se také dozvěděli o parametrech a závorkách a složených závorkách a o tom, kdy je můžete vynechat a kdy ne.

Poté jste se také dozvěděli o implicitním a explicitním návratu, kdy můžete vynechat return prohlášení a kdy ne. Poté jste se naučili, jak vytvořit okamžitě vyvolané funkce šipek. Nakonec jste se také dozvěděli o dvou hlavních rozdílech mezi funkcemi šipek a funkcemi. Tímto vám děkuji za váš čas.