10. května 2017
JavaScript v posledních letech pokročil o tunu. Pokud se učíte JavaScript v roce 2017 a nedotkli jste se ES6, přicházíte o snadnější způsob čtení a zápisu JavaScriptu.
nebojte se, pokud ještě nejste mistrem v JavaScriptu. Nemusíte být úžasní v JavaScriptu, abyste mohli využít přidaných bonusů, které vám ES6 dává. V tomto článku se s vámi chci podělit o osm funkcí ES6, které denně používám jako vývojář, abych vám pomohl zmírnit novou syntaxi.
- seznam funkcí ES6
- Let a const
- Nechť vs var
- Nechť vs const
- funkce šipky
- natvrdlý kostrbatý funkcí šipky
- lexikální toto
- výchozí parametry
- destrukce
- destrukční objekty
- destrukční pole
- výměna proměnných s destruktivními poli
- destrukční pole a objekty při deklaraci funkcí
- parametr rest a operátor spreadu
- zbytek parametr
- operátor spreadu
- Enhanced object literals
- zkratka hodnoty vlastnosti
- metoda shorthands
- názvy vlastností vypočtených objektů
- šablony literály
- balení
seznam funkcí ES6
za prvé, ES6 je obrovská aktualizace JavaScriptu. Zde je velký seznam funkcí, pokud jste zvědaví, co je nového, díky Luke Hoban:
- Arrows
- Classes
- Enhanced object literals
- Template strings
- Destructuring
- Default + rest + spread
- Let + const
- iterátory + pro…
- generátory
- Unicode
- modules
- modules
- map + Set + Weakmap + weakset
- proxy
- symboly
- Subclassable built-ins
- sliby
- math + number + string + array + object API
- binární a osmičkové literály
- reflect API
- ocas volání
nedovolte, aby vás tento velký seznam funkcí vyděsil od ES6. Nemusíte vědět všechno hned. Budu se s vámi podělit o osm z těchto funkcí, které používám denně. Jsou to:
- Let a const
- Arrow funkce
- výchozí parametry
- destrukce
- Rest parametr a spread operátor
- Enhanced object literals
- Template literals
- sliby
projdeme osmi funkcemi v následujících sekcích. Pro teď, projdu prvních pět funkcí. Zbytek přidám za pár týdnů.
mimochodem, podpora prohlížeče pro ES6 je úžasná. Téměř vše je nativně podporováno, pokud kódujete nejnovější prohlížeče (Edge a nejnovější verze FF, Chrome a Safari).
nepotřebujete efektní nástroje, jako je Webpack, pokud jste chtěli napsat ES6. Pokud ve vašem případě chybí podpora prohlížeče, můžete se vždy vrátit k polyfills vytvořeným komunitou. Jen google je:)
s tím, pojďme skočit do první funkce.
Let a const
V ES5 (Starý JavaScript) jsme zvyklí deklarovat proměnné pomocí klíčového slova var
. V ES6 může být toto klíčové slovo var
nahrazeno let
a const
, dvěma výkonnými klíčovými slovy, která usnadňují vývoj.
nejprve se podívejme na rozdíl mezi let
a var
, abychom pochopili, proč jsou let
a const
lepší.
Nechť vs var
pojďme mluvit o var
nejprve, protože jsme s ním obeznámeni.
nejprve můžeme deklarovat proměnné pomocí klíčového slova var
. Po deklaraci lze tuto proměnnou použít kdekoli v aktuálním rozsahu.
var me = 'Zell'console.log(me) // Zell
ve výše uvedeném příkladu jsem deklaroval me
jako globální proměnnou. Tato globální proměnná me
může být také použita ve funkci, jako je tato:
var me = 'Zell'function sayMe () { console.log(me)}sayMe() // Zell
opak však není pravdou. Pokud deklaruji proměnnou ve funkci, nemohu ji použít mimo funkci.
function sayMe() { var me = 'Zell' console.log(me)}sayMe() // Zellconsole.log(me) // Uncaught ReferenceError: me is not defined
takže můžeme říci, že var
je funkční rozsah. To znamená, že kdykoli je ve funkci vytvořena proměnná s var
, bude existovat pouze v rámci funkce.
pokud je proměnná vytvořena mimo funkci, bude existovat ve vnějším rozsahu.
var me = 'Zell' // global scopefunction sayMe () { var me = 'Sleepy head' // local scope console.log(me)}sayMe() // Sleepy headconsole.log(me) // Zell
let
, na druhé straně, je blokově rozsahem. To znamená, že kdykoli je proměnná vytvořena s let
, bude existovat pouze v jejím bloku.
ale počkejte, co je to blok?
blok v JavaScriptu je něco v páru složených závorek. Níže jsou uvedeny příklady bloků.
{ // new scope block}if (true) { // new scope block}while (true) { // new scope block}function () { // new block scope}
rozdíl mezi proměnnými s rozsahem bloků a rozsahem funkcí je obrovský. Pokud použijete proměnnou s rozsahem funkcí, můžete omylem přepsat proměnnou, aniž byste to měli v úmyslu. Zde je příklad:
var me = 'Zell'if (true) { var me = 'Sleepy head'}console.log(me) // 'Sleepy head'
V tomto příkladu můžete vidět, že me
se stane Sleepy head
po spuštění bloku if
. Tento příklad vám pravděpodobně nezpůsobí žádné problémy, protože pravděpodobně nebudete deklarovat proměnné se stejným názvem.
ale každý, kdo pracuje s var
v situaci smyčky for
, může narazit na nějakou podivnost kvůli způsobu, jakým jsou proměnné rozsahem. Zvažte následující kód, který zaznamenává proměnnou i
čtyřikrát, a poté znovu zaznamená i
pomocí funkce setTimeout
.
for (var i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
co byste očekávali, že tento kód udělá? Zde je to, co se vlastně stane
jak se sakra i
stalo 5
čtyřikrát uvnitř funkce timeout? No, ukázalo se, protože var
je rozsahem funkcí, hodnota i
se stala 4
ještě před spuštěním funkce timeout.
abychom získali správnou hodnotu i
v setTimeout
, která se spustí později, musíme vytvořit další funkci, řekněme logLater
, abychom zajistili, že hodnota i
nebude změněna smyčkou for
před provedením setTimeout
:
function logLater (i) { setTimeout(function () { console.log(i) })}for (var i = 1; i < 5; i++) { console.log(i) logLater(i)};
(mimochodem, toto se nazývá uzavření).
dobrou zprávou je, že funkce-scoped weirdness jako příklad pro smyčku, který jsem vám právě ukázal, se nestane s let
. Stejný příklad časového limitu, který jsme napsali dříve, by mohl být napsán jako tento, a bude fungovat hned po vybalení z krabice bez psaní dalších funkcí:
for (let i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
jak vidíte, proměnné s rozsahem bloků usnadňují vývoj odstraněním běžných Gotch s proměnnými s rozsahem funkcí. Chcete-li zjednodušit život, doporučujeme použít let
nad var
vždy, když deklarujete proměnné JavaScriptu od nynějška. (ES6 je nový JavaScript již 😎).
nyní víme, co let
dělá, pojďme k rozdílu mezi let
a const
.
Nechť vs const
jako let
, const
je také blokován-rozsahem. Rozdíl je v tom, že const
nelze po deklaraci znovu přiřadit.
const name = 'Zell'name = 'Sleepy head' // TypeError: Assignment to constant variable.let name1 = 'Zell'name1 = 'Sleepy head'console.log(name1) // 'Sleepy head'
vzhledem k tomu, že const
nelze přeřadit, jsou dobré pro proměnné, které by se nezměnily.
řekněme, že mám tlačítko, které spouští modální na mých webových stránkách. Vím, že tam bude jen jedno tlačítko, a to by se nezměnilo. V tomto případě mohu použít const
.
const modalLauncher = document.querySelector('.jsModalLauncher')
při deklaraci proměnných vždy dávám přednost const
před let
, kdykoli je to možné, protože dostávám další narážku, že proměnná nebude přeřazena. Pak používám let
pro všechny ostatní situace.
dále pojďme dál a mluvíme o funkcích šipek.
funkce šipky
funkce šipky jsou označeny šipkou tuku (=>
), kterou vidíte všude v kódu ES6. Je to zkratka pro anonymní funkce. Mohou být použity kdekoli je použito Klíčové slovo function
. Například:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
funkce šipky jsou docela v pohodě. Pomáhají zkrátit kód, což dává méně prostoru pro skrytí chyb. Pomáhají vám také psát kód, který je srozumitelnější, jakmile si zvyknete na syntaxi.
pojďme se ponořit do natvrdlý-kostrbatý funkcí šipek, takže se naučíte rozpoznat a používat je.
natvrdlý kostrbatý funkcí šipky
nejprve si promluvme o vytváření funkcí. V JavaScriptu jste pravděpodobně zvyklí vytvářet funkce tímto způsobem:
function namedFunction() { // Do something}// using the functionnamedFunction()
existuje druhá metoda pro vytváření funkcí. Můžete vytvořit anonymní funkci a přiřadit ji proměnné. Chcete-li vytvořit anonymní funkci, ponecháme její název mimo deklaraci funkce.
var namedFunction = function() { // Do something}
třetím způsobem, jak vytvořit funkce, je vytvořit je přímo jako argument k jiné funkci nebo metodě. Tento třetí případ použití je nejběžnější pro anonymní funkce. Zde je příklad:
// Using an anonymous function in a callbackbutton.addEventListener('click', function() { // Do something})
protože funkce ES6 arrow jsou zkratkou pro anonymní funkce, můžete nahradit funkce arrow kdekoli, kde vytvoříte anonymní funkci.
tady je to, jak to vypadá:
// Normal Functionconst namedFunction = function (arg1, arg2) { /* do your stuff */}// Arrow Functionconst namedFunction2 = (arg1, arg2) => {/* do your stuff */}// Normal function in a callbackbutton.addEventListener('click', function () { // Do something})// Arrow function in a callbackbutton.addEventListener('click', () => { // Do something})
Vidíte tu podobnost? V podstatě odstraníte Klíčové slovo function
a nahradíte jej =>
na mírně odlišném místě.
ale co je velký problém s funkcemi arrow? Nenahrazujeme function
=>
?
ukázalo se, že nenahrazujeme function
pouze =>
. Syntaxe funkce šipky se může měnit v závislosti na dvou faktorech:
- počet požadovaných argumentů
- zda chcete implicitní návrat.
prvním faktorem je počet argumentů dodaných funkci šipky. Pokud zadáte pouze jeden argument, můžete odstranit závorku, která obklopuje argumenty. Pokud nejsou vyžadovány žádné argumenty, můžete nahradit závorku (()
) podtržítkem (_
).
všechny následující jsou platné funkce šipky.
const zeroArgs = () => {/* do something */}const zeroWithUnderscore = _ => {/* do something */}const oneArg = arg1 => {/* do something */}const oneArgWithParenthesis = (arg1) => {/* do something */}const manyArgs = (arg1, arg2) => {/* do something */}
druhým faktorem pro funkce šipek je, zda chcete implicitní návrat. Funkce Arrow ve výchozím nastavení automaticky vytvoří Klíčové slovo return
, pokud kód zabírá pouze jeden řádek a není uzavřen v bloku.
takže tyto dva jsou ekvivalentní:
const sum1 = (num1, num2) => num1 + num2const sum2 = (num1, num2) => { return num1 + num2 }
tyto dva faktory jsou důvodem, proč můžete psát kratší kód, jako je moreThan20
, který jste viděli výše:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
stručně řečeno, funkce šipky jsou docela v pohodě. Trvá trochu času, než si zvyknou, takže to zkuste a brzy ji budete používat všude.
ale než skočíte na funkci šipky FTW rozjetý vůz, chci vás informovat o dalším drsném rysu funkce šipky ES6, který způsobuje mnoho zmatků-lexikální this
.
lexikální toto
this
je jedinečné Klíčové slovo, jehož hodnota se mění v závislosti na tom, jak se nazývá. Když je volán mimo jakoukoli funkci, this
výchozí objekt Window
v prohlížeči.
console.log(this) // Window
když je this
voláno jednoduchým voláním funkce, this
je nastaveno na globální objekt. V případě prohlížečů bude this
vždy Window
.
function hello () { console.log(this)}hello() // Window
JavaScript vždy nastaví this
na objekt okna v rámci jednoduchého volání funkce. To vysvětluje, proč hodnota this
ve funkcích jako setTimeout
je vždy Window
.
když je this
voláno metodou objektu, this
by byl objekt sám:
let o = { sayThis: function() { console.log(this) }}o.sayThis() // o
když je funkce volána jako konstruktor, this
odkazuje na nově vytvořený objekt.
function Person (age) { this.age = age}let greg = new Person(22)let thomas = new Person(24)console.log(greg) // this.age = 22console.log(thomas) // this.age = 24
při použití v posluchači událostí je this
nastaven na prvek, který vypálil událost.
let button = document.querySelector('button')button.addEventListener('click', function() { console.log(this) // button})
jak můžete vidět ve výše uvedených situacích, hodnota this
je nastavena funkcí, která ji volá. Každá funkce definuje vlastní hodnotu this
.
ve funkcích fat arrow se this
nikdy neváže na novou hodnotu, bez ohledu na to, jak se funkce nazývá. this
bude vždy stejná hodnota this
jako jeho okolní kód. (Mimochodem, lexikální prostředky týkající se, což myslím, je to, jak lexikální this
dostal své jméno).
dobře, to zní matoucí, takže pojďme projít několik skutečných příkladů.
nejprve nikdy nechcete používat funkce šipky k deklarování metod objektů, protože již nemůžete odkazovat na objekt s this
.
let o = { // Don't do this notThis: () => { console.log(this) // Window this.objectThis() // Uncaught TypeError: this.objectThis is not a function }, // Do this objectThis: function () { console.log(this) // o } // Or this, which is a new shorthand objectThis2 () { console.log(this) // o }}
za druhé, možná nebudete chtít použít funkce šipky k vytvoření posluchačů událostí, protože this
se již neváže na prvek, ke kterému jste připojili posluchače událostí.
vždy však můžete získat správný kontext this
s event.currentTarget
. Proto jsem řekl, že nesmí.
button.addEventListener('click', function () { console.log(this) // button})button.addEventListener('click', e => { console.log(this) // Window console.log(event.currentTarget) // button})
za třetí, možná budete chtít použít lexikální this
v místech, kde se vazba this
mění, aniž byste to chtěli. Příkladem je funkce timeout, takže se nikdy nebudete muset zabývat nesmysly this
, that
nebo self
.
let o = { // Old way oldDoSthAfterThree: function () { let that = this setTimeout(function () { console.log(this) // Window console.log(that) // o }) }, // Arrow function way doSthAfterThree: function () { setTimeout(() => { console.log(this) // o }, 3000) }}
tento případ použití je obzvláště užitečný, pokud potřebujete přidat nebo odebrat třídu po uplynutí určité doby:
let o = { button: document.querySelector('button') endAnimation: function () { this.button.classList.add('is-closing') setTimeout(() => { this.button.classList.remove('is-closing') this.button.classList.remove('is-open') }, 3000) }}
A konečně, neváhejte použít funkci fat arrow kdekoli jinde, aby váš kód byl čistší a kratší, jako příklad moreThan20
, který jsme měli výše:
let array = let moreThan20 = array.filter(num => num > 20)
pojďme dál.
výchozí parametry
výchozí parametry v ES6 … no, nám dává způsob, jak určit výchozí parametry, když definujeme funkce. Pojďme si projít příklad a uvidíte, jak je to užitečné.
řekněme, že vytváříme funkci, která oznamuje jméno hráče z týmu. Pokud tuto funkci zapíšete do ES5, bude to podobné následujícímu:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
na první pohled vypadá tento kód v pořádku. Ale co kdybychom měli oznámit hráče, který není spojen s žádným týmem?
aktuální kód se rozpačitě nezdaří, pokud jsme vynechali teamName
:
announcePlayer('Zell', 'Liew')// Zell Liew, undefined
jsem si docela jistý, že undefined není tým.
pokud je hráč nepřidružený, oznamování Zell Liew, unaffiliated
by dávalo větší smysl než Zell Liew, undefined
. Nesouhlasíte?
Chcete-li získat announcePlayer
oznámit Zell Liew, unaffiliated
, jedním ze způsobů je předat řetězec unaffiliated
jako teamName
:
announcePlayer('Zell', 'Liew', 'unaffiliated')// Zell Liew, unaffiliated
i když to funguje, můžeme to udělat lépe refaktorováním unaffiliated
do announcePlayer
kontrolou, zda je definováno teamName
.
ve verzi ES5 můžete refaktorovat kód na něco takového:
function announcePlayer (firstName, lastName, teamName) { if (!teamName) { teamName = 'unaffiliated' } console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Zell', 'Liew')// Zell Liew, unaffiliatedannouncePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
nebo, pokud jste důvtipnější u ternárních operátorů, mohli jste si vybrat verzi terser:
function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated' console.log(firstName + ' ' + lastName + ', ' + team)}
V ES6, s výchozími parametry, můžeme přidat znaménko rovnosti (=
), kdykoli definujeme parametr. Pokud tak učiníme, ES6 automaticky nastaví výchozí hodnotu, když parametr není definován.
takže v tomto kódu níže, pokud je teamName
nedefinováno, je výchozí hodnota unaffiliated
:
const announcePlayer = (firstName, lastName, teamName = 'unaffiliated') => { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Zell', 'Liew')// Zell Liew, unaffiliatedannouncePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
docela v pohodě, že? 🙂
ještě jedna věc. Pokud chcete vyvolat výchozí hodnotu, můžete zadat undefined
ručně. Tato příručka předání undefined
pomáhá, když váš výchozí parametr není posledním argumentem funkce.
announcePlayer('Zell', 'Liew', undefined)// Zell Liew, unaffiliated
To je vše, co potřebujete vědět o výchozích parametrech. Je to jednoduché a velmi užitečné 🙂
destrukce
destrukce je pohodlný způsob, jak získat hodnoty z polí a objektů. Existují malé rozdíly mezi destrukčním polem a objekty, takže o nich hovoříme zvlášť.
destrukční objekty
řekněme, že máte následující objekt:
const Zell = { firstName: 'Zell', lastName: 'Liew'}
Chcete-li získat firstName
a lastName
z Zell
, museli jste vytvořit dvě proměnné a přiřadit každou proměnnou hodnotě, jako je tato:
let firstName = Zell.firstName // Zelllet lastName = Zell.lastName // Liew
při destrukci můžete tyto proměnné vytvořit a přiřadit pomocí jediného řádku kódu. Zde je návod, jak ničit objekty:
let { firstName, lastName } = Zellconsole.log(firstName) // Zellconsole.log(lastName) // Liew
vidíš, co se tu stalo? Přidáním složených závorek ({}
) při deklaraci proměnných říkáme JavaScriptu, aby vytvořil výše uvedené proměnné, a poté přiřaďte Zell.firstName
firstName
a Zell.lastName
lastName
.
To je to, co se děje pod kapotou:
// What you writelet { firstName, lastName } = Zell// ES6 does this automaticallylet firstName = Zell.firstNamelet lastName = Zell.lastName
Nyní, pokud je název proměnné již použit, nemůžeme tuto proměnnou znovu deklarovat (zejména pokud používáte let
nebo const
).
následující nefunguje:
let name = 'Zell Liew'let course = { name: 'JS Fundamentals for Frontend Developers' // ... other properties}let { name } = course // Uncaught SyntaxError: Identifier 'name' has already been declared
pokud narazíte na situace, jako je výše, můžete přejmenovat proměnné při destrukci dvojtečkou (:
).
v tomto příkladu níže vytvářím proměnnou courseName
a přiřazuji jí course.name
.
let { name: courseName } = courseconsole.log(courseName) // JS Fundamentals for Frontend Developers// What ES6 does under the hood:let courseName = course.name
ještě jedna věc.
nebojte se, pokud se pokusíte zničit proměnnou, která není obsažena v objektu. Vrátí se undefined
.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package } = courseconsole.log(package) // undefined
ale počkejte, to není vše. Pamatujete si výchozí parametry?
můžete také zapsat výchozí parametry pro své destrukční proměnné. Syntaxe je stejná jako při definování funkcí.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package = 'full course' } = courseconsole.log(package) // full course
můžete dokonce přejmenovat proměnné při poskytování výchozích hodnot. Stačí je zkombinovat. Na začátku to bude vypadat trochu vtipně, ale zvyknete si na to, pokud jej používáte často:
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package: packageName = 'full course' } = courseconsole.log(packageName) // full course
To je vše pro ničení objektů. Pojďme dál a mluvíme o destrukci polí 😄.
destrukční pole
destrukční pole a destrukční objekty jsou podobné. Místo složených závorek ({}
) používáme hranaté závorky ().
když zničíte pole,
- vaše první proměnná je první položka v poli.
- vaše druhá proměnná je druhou položkou v poli.
- a tak dále…
let = console.log(one) // 1console.log(two) // 2
je možné zničit tolik proměnných, že překročíte počet položek v daném poli. Když k tomu dojde, extra destrukční proměnná bude jen undefined
.
let = console.log(one) // 1console.log(two) // 2console.log(three) // undefined
při destrukci polí často destrukujeme pouze proměnné, které potřebujeme. Pokud potřebujete zbytek pole, můžete použít zbytek operátora (...
), takto:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93console.log(rest) //
více o provozovatelích odpočinku si povíme v následující části. Ale prozatím si promluvme o jedinečné schopnosti, kterou získáte s destruktivními poli-vyměňováním proměnných.
výměna proměnných s destruktivními poli
řekněme, že máte dvě proměnné, a
a b
.
let a = 2let b = 3
chtěli jste tyto proměnné vyměnit. Takže a = 3
a b = 2
. V ES5 musíte k dokončení swapu použít dočasnou třetí proměnnou:
let a = 2let b = 3let temp// swappingtemp = a // temp is now 2a = b // a is now 3b = temp // b is now 2
ačkoli to funguje, logika může být nejasná a matoucí, zejména se zavedením třetí proměnné.
nyní sledujte, jak to uděláte ES6 způsobem s destruktivními poli:
let a = 2let b = 3; // semicolon required because next line begins with a square bracket// Swapping with destructured arrays = console.log(a) // 3console.log(b) // 2
💥💥💥. Mnohem jednodušší ve srovnání s předchozí metodou výměny proměnných! 🙂
dále hovoříme o destrukci polí a objektů ve funkci.
destrukční pole a objekty při deklaraci funkcí
nejúžasnější věc na destrukci je, že je můžete použít kdekoli. Doslova. Můžete dokonce zničit objekty a pole ve funkcích.
řekněme, že máme funkci, která přijímá pole skóre a vrací objekt se třemi nejlepšími skóre. Tato funkce je podobná tomu, co jsme udělali při destrukci polí.
// Note: You don't need arrow functions to use any other ES6 featuresfunction topThree (scores) { let = scores return { first: first, second: second, third: third }}
alternativní způsob zápisu této funkce je zničení scores
při deklaraci funkce. V tomto případě je o jeden řádek kódu méně. Zároveň víme, že přijímáme řadu.
function topThree () { return { first: first, second: second, third: third }}
Super cool, že? 😄.
nyní je zde rychlý malý kvíz pro vás. Protože můžeme kombinovat výchozí parametry a destrukci při deklaraci funkcí, co říká následující?
function sayMyName ({ firstName = 'Zell', lastName = 'Liew'} = {}) { console.log(firstName + ' ' + lastName)}
To je složité. Kombinujeme několik funkcí dohromady.
nejprve vidíme, že tato funkce má jeden argument, objekt. Tento objekt je volitelný a při nedefinování je výchozí hodnota {}
.
za druhé se pokusíme z daného objektu zničit proměnné firstName
a lastName
. Pokud jsou tyto vlastnosti nalezeny, použijte je.
A konečně, pokud je firstName
nebo lastName
v daném objektu nedefinováno, nastavíme jej na Zell
a Liew
.
takže tato funkce produkuje následující výsledky:
sayMyName() // Zell LiewsayMyName({firstName: 'Zell'}) // Zell LiewsayMyName({firstName: 'Vincy', lastName: 'Zhang'}) // Vincy Zhang
docela v pohodě kombinovat destrukci a výchozí parametry v deklaraci funkce, co? 😄. Miluju to.
dále se podívejme na odpočinek a šíření.
parametr rest a operátor spreadu
parametr rest a operátor spreadu vypadají stejně. Obě jsou označeny třemi tečkami (...
).
To, co dělají, se liší v závislosti na tom, k čemu se používají. Proto se jmenují jinak. Podívejme se tedy na parametr rest a operátor spread Samostatně.
zbytek parametr
volně přeloženo, zbytek parametr znamená vzít zbytek věci a zabalit do pole. Převádí čárkami oddělený seznam argumentů do pole.
pojďme se podívat na parametr rest v akci. Představte si, že máme funkci add
, která shrnuje její argumenty:
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 55
V ES5 jsme záviseli na proměnné arguments
, kdykoli jsme se museli vypořádat s funkcí, která přijímá neznámý počet proměnných. Tato proměnná arguments
je pole podobné Symbol
.
function sum () { console.log(arguments)}sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
jedním ze způsobů, jak vypočítat tento součet argumentů, je převést jej na pole s Array.prototype.slice.call(arguments)
a poté procházet každé číslo metodou pole jako forEach
nebo reduce
.
jsem si jistý, že můžete udělat forEach
sami, takže zde je příklad reduce
:
// ES5 wayfunction sum () { let argsArray = Array.prototype.slice.call(arguments) return argsArray.reduce(function(sum, current) { return sum + current }, 0)}
s parametrem ES6 rest bychom mohli všechny argumenty oddělené čárkami zabalit přímo do pole.
// ES6 wayconst sum = (...args) => args.reduce((sum, current) => sum + current, 0)// ES6 way if we didn't shortcut it with so many arrow functionsfunction sum (...args) { return args.reduce((sum, current) => sum + current, 0)}
mnohem čistší? 🙂.
nyní jsme se krátce setkali s parametrem rest dříve v sekci destrukce. Tam, pokusili jsme se zničit řadu skóre do prvních tří skóre:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93
pokud bychom chtěli zbytek skóre, mohli bychom tak učinit zabalením zbytku skóre do pole se zbytkovým parametrem.
let scores = let = scoresconsole.log(restOfScores) //
pokud jste někdy zmateni, nezapomeňte na to-zbytek parametru zabalí vše do pole. Objevuje se ve funkčních parametrech a při destrukčních polích.
dále přejdeme k šíření.
operátor spreadu
operátor spreadu se chová opačně ve srovnání s parametrem rest. Volně řečeno, vezme pole a rozšíří jej (jako jam) do čárkami odděleného seznamu argumentů.
let array = // These two are exactly the sameconsole.log(...array) // one two threeconsole.log('one', 'two', 'three') // one two three
operátor šíření se často používá k tomu, aby pomohl zřetězit pole způsobem, který je snáze čitelný a srozumitelný.
řekněme například, že jste chtěli zřetězit následující pole:
let array1 = let array2 = let array3 =
ES5 způsob zřetězení těchto dvou polí je použití metody Array.concat
. Můžete řetězec více Array.concat
zřetězit libovolný počet polí, jako je tento:
// ES5 waylet combinedArray = array1.concat(array2).concat(array3)console.log(combinedArray) //
s operátorem šíření ES6 můžete pole rozložit do nového pole, jako je toto, což je o něco snazší číst, jakmile si na to zvyknete:
// ES6 waylet combinedArray = console.log(combinedArray) //
operátor šíření lze také použít k odstranění položky z pole bez mutace pole. Tato metoda se běžně používá v Reduxu. Vřele doporučuji sledovat toto video Dan Abramov, pokud máte zájem vidět, jak to funguje.
To je pro spread:)
Enhanced object literals
objekty by vám měly být známé, protože píšete JavaScript. Jen v případě, že o nich nevíte, vypadají nějak takto:
const anObject = { property1: 'value1', property2: 'value2', property3: 'value3',}
ES6 enhanced object literals přináší tři sladké upgrady na objekty, které znáte a milujete. Jsou to:
- hodnota vlastnosti shorthands
- metoda shorthands
- schopnost používat vypočtené názvy vlastností
podívejme se na každou z nich. Slibuji, že to bude rychlé:)
zkratka hodnoty vlastnosti
všimli jste si, že někdy přiřadíte proměnnou, která má stejný název jako vlastnost objektu? Víte, něco takového:
const fullName = 'Zell Liew'const Zell = { fullName: fullName}
no, nechtěli byste, abyste to mohli napsat kratším způsobem, protože vlastnost (fullName
) a hodnota (fullName
)?
(Ach ty rozmazlený spratku).
zde je dobrá zpráva. Můžeš! 🙂
ES6 vylepšuje objekty s hodnotou vlastností shorthands. To znamená: proměnnou můžete psát pouze tehdy, pokud se název proměnné shoduje s názvem vaší vlastnosti. ES6 se postará o zbytek.
tady je to, jak to vypadá:
const fullName = 'Zell Liew'// ES6 wayconst Zell = { fullName}// Underneath the hood, ES6 does this:const Zell = { fullName: fullName}
pěkný, co? Teď máme méně slov na psaní a všichni jdeme domů šťastní.
zatímco tančím, pokračujte prosím a přejděte k více těsnopis dobroty. Brzy se k vám přidám.
metoda shorthands
metody jsou funkce, které jsou spojeny s vlastností. Jsou pojmenovány speciálně, protože jsou to funkce:)
Toto je příklad metody:
const anObject = { aMethod: function () { console.log("I'm a method!~~")}}
S ES6 se dostaneme k psaní metod se zkratkou. Můžeme odstranit : function
z Deklarace metody a bude fungovat jako dříve:
const anObject = { // ES6 way aShorthandMethod (arg1, arg2) {}, // ES5 way aLonghandMethod: function (arg1, arg2) {},}
S touto aktualizací objekty již získají zkratkovou metodu, takže při definování objektů prosím nepoužívejte funkce šipky. Přerušíte kontext this
(viz funkce šipky, pokud si nepamatujete proč).
const dontDoThis = { // Noooo. Don't do this arrowFunction: () => {}}
To je vše s objektovou metodou shorthands. Pojďme k finálnímu upgradu, který získáme pro objekty.
názvy vlastností vypočtených objektů
někdy potřebujete dynamický název vlastnosti při vytváření objektů. Ve starém JavaScript způsobem, budete muset vytvořit objekt, pak přiřadit svůj majetek in, takhle:
// ES5const newPropertyName = 'smile'// Create an object firstconst anObject = { aProperty: 'a value' }// Then assign the propertyanObject = ':D'// Adding a slightly different property and assigning itanObject = 'XD'// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }
V ES6 již nemusíte dělat tento kruhový objezd. Dynamické názvy vlastností můžete přiřadit přímo při vytváření objektu. Klíčem je uzavřít dynamickou vlastnost hranatými závorkami:
const newPropertyName = 'smile'// ES6 way.const anObject = { aProperty: 'a value', // Dynamic property names! : ':D', : 'XD',}// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }
Schweeete! Není to tak? 🙂
A to je vše pro vylepšené literály objektů. Neříkal jsem, že to bude rychlé? 🙂
přejděme k další úžasné funkci, kterou naprosto miluji: template literals.
šablony literály
zpracování řetězců v JavaScriptu je extrémně neohrabaný zážitek. Sami jste to zažili, když jsme dříve vytvořili funkci announcePlayer
ve výchozích parametrech. Tam jsme vytvořili mezery s prázdnými řetězci a spojili je s plusy:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}
V ES6 tento problém zmizí díky šablonovým literálům! (Ve specifikaci se dříve nazývaly řetězce šablon).
Chcete-li vytvořit literál šablony v ES6, uzavřete řetězce backticks (`
). V rámci backticks získáte přístup ke speciálnímu zástupnému symbolu (${}
), kde můžete normálně používat JavaScript.
zde je to, jak to vypadá v akci:
const firstName = 'Zell'const lastName = 'Liew'const teamName = 'unaffiliated'const theString = `${firstName} ${lastName}, ${teamName}`console.log(theString)// Zell Liew, unaffiliated
Vidíš to? Můžeme seskupit vše s šablonovými literály! V šablonových literálech je to Angličtina jako obvykle. Skoro jako bychom používali šablonový motor:)
nejlepší část o šablonových literálech je, že můžete snadno vytvářet víceřádkové řetězce. To funguje po vybalení z krabice:
const multi = `One upon a time,In a land far far away,there lived a witich,who could change night into day`
jedním z úhledných triků je použití těchto řetězců k vytvoření prvků HTML v JavaScriptu, pokud je potřebujete. (Poznámka: To nemusí být nejlepší způsob, jak vytvořit prvky HTML, ale je to stále lepší než jejich vytváření jeden po druhém!).
const container = document.createElement('div')const aListOfItems = `<ul> <li>Point number one</li> <li>Point number two</li> <li>Point number three</li> <li>Point number four</li> </ul>`container.innerHTML = aListOfItemsdocument.body.append(container)
viz pero pomocí víceřádkových řetězců k vytvoření složitějších prvků HTML od Zell Liew (@zellwk) na CodePen.
další funkce literálů šablon se nazývá značky. Tagy jsou funkce, které vám umožňují manipulovat s doslovem šablony, pokud chcete nahradit jakýkoli řetězec.
tady je to, jak to vypadá:
const animal = 'lamb'// This a tagconst tagFunction = () => { // Do something here}// This tagFunction allows you to manipulate the template literal.const string = tagFunction `Mary had a little ${animal}`
abych byl upřímný, i když značky šablon vypadají skvěle, ještě jsem pro ně neměl případ použití. Pokud se chcete dozvědět více o značkách šablon, doporučujeme vám přečíst si tento odkaz na MDN.
To je vše pro literály šablon.
balení
Woo! To jsou téměř všechny úžasné funkce ES6, které pravidelně používám. ES6 je úžasný. Rozhodně stojí za to věnovat trochu času a dozvědět se o nich, abyste pochopili, o čem všichni ostatní píší.