10th May 2017
JavaScript poczynił ogromne postępy w ostatnich latach. Jeśli uczysz się JavaScript w 2017 roku i nie dotknąłeś ES6, tracisz łatwiejszy sposób czytania i pisania JavaScript.
nie martw się, jeśli nie jesteś jeszcze mistrzem JavaScript. Nie musisz być niesamowity w JavaScript, aby skorzystać z dodanych bonusów, które daje Ci ES6. W tym artykule chcę podzielić się z wami ośmioma funkcjami ES6, których używam codziennie jako programista, aby ułatwić Wam korzystanie z nowej składni.
- lista funkcji ES6
- Let i const
- Let vs var
- Let vs const
- funkcje strzałek
- nitty-gritty funkcji strzałek
- leksykalny ten
- domyślne parametry
- Destructuring
- niszczenie obiektów
- Tablice destrukcyjne
- Zamiana zmiennych ze zniszczonymi tablicami
- destrukcja tablic i obiektów podczas deklarowania funkcji
- parametr rest i operator spreadu
- parametr rest
- Operator spreadu
- Rozszerzone literały obiektów
- skróty wartości właściwości
- skróty metod
- obliczone nazwy właściwości obiektów
- literały szablonów
lista funkcji ES6
po pierwsze, ES6 jest ogromną aktualizacją JavaScript. Oto duża lista funkcji, jeśli jesteś ciekawy, co nowego, dzięki Luke Hoban:
- Strzałki
- klasy
- ulepszone literały obiektów
- ciągi szablonów
- destrukcja
- Default + rest + spread
- Let + const
- Iteratory + dla…2224>
- generatory
- Unicode
- Moduły
- ładowarki modułów
- map + set + WeakMap + WeakSet
- proxy
- Symbole
- wbudowane podklasy
- obietnice
- Math + Number + string + array + object API
- literały binarne i ósemkowe
- reflect API
- Tail połączenia
nie pozwól, aby ta duża lista funkcji odstraszyła Cię od ES6. Nie musisz wiedzieć wszystkiego od razu. Podzielę się z wami ośmioma z tych funkcji, których używam na co dzień. Są to:
- Let i const
- funkcje strzałek
- domyślne parametry
- destrukcja
- Operator parametru Rest I spread
- ulepszone literały obiektów
- literały szablonów
- obietnice
będziemy przejdź przez osiem funkcji w następujących sekcjach. Na razie przejdę przez pięć pierwszych funkcji. Resztę dodam w ciągu najbliższych kilku tygodni.
nawiasem mówiąc, obsługa przeglądarki dla ES6 jest niesamowita. Prawie wszystko jest obsługiwane natywnie, jeśli kodujesz dla najnowszych przeglądarek (Edge i najnowsze wersje FF, Chrome i Safari).
nie potrzebujesz fantazyjnych narzędzi, takich jak Webpack, jeśli chcesz napisać ES6. Jeśli w Twoim przypadku brakuje wsparcia dla przeglądarki, zawsze możesz skorzystać z polyfills stworzonych przez społeczność. Wystarczy je wygooglować:)
z tym przejdźmy do pierwszej funkcji.
Let i const
W ES5 (starym JavaScript) jesteśmy przyzwyczajeni do deklarowania zmiennych za pomocą słowa kluczowego var
. W ES6, to var
słowo kluczowe może być zastąpione przez let
i const
, dwa potężne słowa kluczowe, które ułatwiają rozwój.
najpierw spójrzmy na różnicę między let
i var
, aby zrozumieć, dlaczego let
i const
są lepsze.
Let vs var
porozmawiajmy najpierw o var
, ponieważ znamy go.
przede wszystkim możemy zadeklarować zmienne za pomocą słowa kluczowego var
. Po zadeklarowaniu, zmienna ta może być używana w dowolnym miejscu w bieżącym zakresie.
var me = 'Zell'console.log(me) // Zell
w powyższym przykładzie zadeklarowałem me
jako zmienną globalną. Ta globalna zmienna me
może być również użyta w funkcji, jak ta:
var me = 'Zell'function sayMe () { console.log(me)}sayMe() // Zell
jednak odwrotna sytuacja nie jest prawdziwa. Jeśli zadeklaruję zmienną w funkcji, nie mogę jej używać poza funkcją.
function sayMe() { var me = 'Zell' console.log(me)}sayMe() // Zellconsole.log(me) // Uncaught ReferenceError: me is not defined
możemy więc powiedzieć, że var
ma zasięg funkcji. Oznacza to, że gdy zmienna jest tworzona z var
w funkcji, będzie istnieć tylko wewnątrz funkcji.
jeśli zmienna jest tworzona poza funkcją, będzie istnieć w zewnętrznym zakresie.
var me = 'Zell' // global scopefunction sayMe () { var me = 'Sleepy head' // local scope console.log(me)}sayMe() // Sleepy headconsole.log(me) // Zell
let
, z drugiej strony, jest zablokowany. Oznacza to, że gdy zmienna zostanie utworzona z let
, będzie istnieć tylko w jej bloku.
ale czekaj, co to jest blok?
blok w JavaScript to wszystko w parze nawiasów klamrowych. Poniżej znajdują się przykłady bloków.
{ // new scope block}if (true) { // new scope block}while (true) { // new scope block}function () { // new block scope}
różnica między zmiennymi o zasięgu bloku a zmiennymi o zasięgu funkcji jest ogromna. Kiedy używasz zmiennej o zasięgu funkcyjnym, możesz przypadkowo nadpisać zmienną bez zamiaru tego robić. Oto przykład:
var me = 'Zell'if (true) { var me = 'Sleepy head'}console.log(me) // 'Sleepy head'
W tym przykładzie możesz zobaczyć, że me
staje się Sleepy head
po uruchomieniu bloku if
. Ten przykład prawdopodobnie nie spowoduje żadnych problemów, ponieważ prawdopodobnie nie będziesz deklarował zmiennych o tej samej nazwie.
ale każdy, kto pracuje z var
w sytuacji pętli for
, może napotkać pewne dziwactwo ze względu na sposób, w jaki zmienne są zakreślane. Rozważ następujący kod, który rejestruje zmienną i
cztery razy, a następnie rejestruje i
ponownie za pomocą funkcji setTimeout
.
for (var i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
czego oczekujesz od tego kodu? Oto co się właściwie dzieje
jak do cholery i
stał się 5
cztery razy w funkcji timeout? Okazuje się, że ponieważ var
ma zasięg funkcji, wartość i
stała się 4
jeszcze przed uruchomieniem funkcji timeout.
aby uzyskać poprawną wartość i
w setTimeout
, która zostanie wykonana później, musimy utworzyć inną funkcję, powiedzmy logLater
, aby upewnić się, że wartość i
nie zostanie zmieniona przez pętlę for
przed wykonaniem setTimeout
:
function logLater (i) { setTimeout(function () { console.log(i) })}for (var i = 1; i < 5; i++) { console.log(i) logLater(i)};
(nawiasem mówiąc, nazywa się to zamknięciem).
dobra wiadomość jest taka, że dziwactwo funkcji, takie jak przykład pętli for, który właśnie ci pokazałem, nie dzieje się z let
. Ten sam przykład limitu czasu, który napisaliśmy wcześniej, może być zapisany jako ten i będzie działał od razu po wyjęciu z pudełka bez pisania dodatkowych funkcji:
for (let i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
jak widać, zmienne o zasięgu blokowym znacznie ułatwiają rozwój, usuwając zwykłe Gotcha ze zmiennymi o zasięgu funkcyjnym. Aby uczynić życie prostszym, zalecam użycie let
zamiast var
za każdym razem, gdy deklarujesz zmienne JavaScript od teraz. (ES6 to już nowy JavaScript).
teraz wiemy, co robi let
, przejdźmy do różnicy między let
i const
.
Let vs const
podobnie jak let
, const
jest również zablokowany-scoped. Różnica polega na tym, że const
nie można ponownie przypisać po zadeklarowaniu.
const name = 'Zell'name = 'Sleepy head' // TypeError: Assignment to constant variable.let name1 = 'Zell'name1 = 'Sleepy head'console.log(name1) // 'Sleepy head'
ponieważ const
nie można ponownie przypisać, są dobre dla zmiennych, które się nie zmienią.
powiedzmy, że mam przycisk, który uruchamia modal na mojej stronie. Wiem, że będzie tylko jeden przycisk, i to się nie zmieni. W tym przypadku mogę użyć const
.
const modalLauncher = document.querySelector('.jsModalLauncher')
deklarując zmienne, zawsze wolę const
niż let
, jeśli to możliwe, ponieważ otrzymuję dodatkowy sygnał, że zmienna nie zostanie ponownie przypisana. Następnie używam let
do wszystkich innych sytuacji.
następnie przejdźmy dalej i porozmawiajmy o funkcjach strzałek.
funkcje strzałek
funkcje strzałek są oznaczone strzałką fat (=>
), którą widzisz wszędzie w kodzie ES6. To skrót do tworzenia anonimowych funkcji. Mogą być używane wszędzie tam, gdzie używane jest słowo kluczowe function
. Na przykład:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
funkcje strzałek są całkiem fajne. Pomagają skrócić Kod, co daje mniej miejsca na błędy do ukrycia. Pomagają również w pisaniu kodu, który jest łatwiejszy do zrozumienia, gdy przyzwyczaisz się do składni.
zagłębimy się w szczegóły funkcji strzałek, abyś nauczył się ich rozpoznawać i używać.
nitty-gritty funkcji strzałek
po pierwsze, porozmawiajmy o tworzeniu funkcji. W JavaScript, prawdopodobnie jesteś przyzwyczajony do tworzenia funkcji w ten sposób:
function namedFunction() { // Do something}// using the functionnamedFunction()
jest druga metoda tworzenia funkcji. Możesz utworzyć funkcję anonimową i przypisać ją do zmiennej. Aby utworzyć funkcję anonimową, zostawiamy jej nazwę poza deklaracją funkcji.
var namedFunction = function() { // Do something}
trzecim sposobem tworzenia funkcji jest utworzenie ich bezpośrednio jako argumentu do innej funkcji lub metody. Ten trzeci przypadek użycia jest najczęstszym dla funkcji anonimowych. Oto przykład:
// Using an anonymous function in a callbackbutton.addEventListener('click', function() { // Do something})
ponieważ funkcje strzałek ES6 są skrótem od funkcji anonimowych, możesz zastąpić funkcje strzałek w dowolnym miejscu, w którym utworzysz funkcję anonimową.
oto jak to wygląda:
// 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})
widzisz podobieństwo? Zasadniczo usuwasz słowo kluczowe function
i zastępujesz je =>
w nieco innej lokalizacji.
ale o co chodzi z funkcjami strzałek? Czy nie zamieniamy function
na =>
?
cóż, okazuje się, że nie zastępujemy function
=>
. Składnia funkcji strzałki może się zmieniać w zależności od dwóch czynników:
- liczba wymaganych argumentów
- niezależnie od tego, czy chcesz uzyskać Ukryty zwrot.
pierwszym czynnikiem jest liczba argumentów dostarczonych do funkcji arrow. Jeśli podasz tylko jeden argument, możesz usunąć nawias otaczający argumenty. Jeśli nie są wymagane żadne argumenty, możesz zastąpić nawias (()
) znakiem podkreślenia (_
).
Wszystkie poniższe funkcje są poprawnymi funkcjami strzałek.
const zeroArgs = () => {/* do something */}const zeroWithUnderscore = _ => {/* do something */}const oneArg = arg1 => {/* do something */}const oneArgWithParenthesis = (arg1) => {/* do something */}const manyArgs = (arg1, arg2) => {/* do something */}
drugim czynnikiem dla funkcji strzałek jest to, czy chcesz uzyskać niejawny zwrot. Funkcje strzałek domyślnie automatycznie tworzą słowo kluczowe return
, jeśli kod zajmuje tylko jedną linię I nie jest zamknięty w bloku.
więc te dwa są równoważne:
const sum1 = (num1, num2) => num1 + num2const sum2 = (num1, num2) => { return num1 + num2 }
te dwa czynniki są powodem, dla którego możesz napisać krótszy Kod, jak moreThan20
, który widziałeś powyżej:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
podsumowując, funkcje strzałek są całkiem fajne. Potrzeba trochę czasu, aby się przyzwyczaić, więc spróbuj, a wkrótce będziesz go używać wszędzie.
ale zanim przejdziesz do funkcji strzałek FTW, chcę ci powiedzieć o innej nitty-gritty funkcji strzałki ES6, które powodują wiele zamieszania-leksykalny this
.
leksykalny ten
this
jest unikalnym słowem kluczowym, którego wartość zmienia się w zależności od tego, jak jest wywoływany. Gdy jest wywoływany poza dowolną funkcją, this
domyślnie jest to obiekt Window
w przeglądarce.
console.log(this) // Window
gdy this
jest wywołane w prostym wywołaniu funkcji, this
jest ustawione na obiekt globalny. W przypadku przeglądarek this
zawsze będzie Window
.
function hello () { console.log(this)}hello() // Window
JavaScript zawsze ustawia this
na obiekt window w ramach prostego wywołania funkcji. To wyjaśnia, dlaczego wartość this
w funkcjach takich jak setTimeout
jest zawsze Window
.
gdy this
jest wywoływana w metodzie obiektu, this
byłby sam obiekt:
let o = { sayThis: function() { console.log(this) }}o.sayThis() // o
gdy funkcja jest wywoływana jako konstruktor, this
odnosi się do nowo zbudowanego obiektu.
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
gdy jest używany w detektorze zdarzeń, this
jest ustawiany na element, który wywołał zdarzenie.
let button = document.querySelector('button')button.addEventListener('click', function() { console.log(this) // button})
jak widać w powyższych sytuacjach, wartość this
jest ustawiana przez funkcję, która ją wywołuje. Każda funkcja definiuje własną wartość this
.
w funkcjach strzałek fat, this
nigdy nie jest związana z nową wartością, bez względu na to, jak funkcja jest wywoływana. this
zawsze będzie tą samą wartością this
co otaczający go kod. (Nawiasem mówiąc, środki leksykalne odnoszące się do, czyli chyba tak leksykalny this
dostał swoją nazwę).
OK, to brzmi myląco, więc przejdźmy przez kilka prawdziwych przykładów.
po pierwsze, nie chcesz używać funkcji strzałek do deklarowania metod obiektu, ponieważ nie możesz już odwoływać się do obiektu za pomocą 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 }}
po drugie, możesz nie używać funkcji strzałek do tworzenia detektorów zdarzeń, ponieważ this
nie wiąże się już z elementem, do którego został dołączony detektor zdarzeń.
jednak zawsze możesz uzyskać właściwy this
kontekst za pomocą event.currentTarget
. Dlatego powiedziałem, że nie wolno.
button.addEventListener('click', function () { console.log(this) // button})button.addEventListener('click', e => { console.log(this) // Window console.log(event.currentTarget) // button})
Po trzecie, możesz użyć leksykalnego this
w miejscach, w których Wiązanie this
zmienia się bez Twojej zgody. Przykładem jest funkcja timeout, więc nigdy nie musisz zajmować się nonsensem this
, that
lub 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) }}
ten przypadek użycia jest szczególnie przydatny, jeśli potrzebujesz dodać lub usunąć klasę po upływie pewnego czasu:
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) }}
na koniec możesz używać funkcji strzałki fat gdziekolwiek indziej, aby pomóc w uporządkowaniu i skróceniu kodu, jak w przykładzie moreThan20
, który mieliśmy powyżej:
let array = let moreThan20 = array.filter(num => num > 20)
przejdźmy dalej.
domyślne parametry
domyślne parametry w ES6 … cóż, daje nam sposób na określenie domyślnych parametrów podczas definiowania funkcji. Przejdźmy przez przykład, a zobaczysz, jak pomocne jest to.
powiedzmy, że tworzymy funkcję, która ogłasza nazwę Gracza z drużyny. Jeśli napiszesz tę funkcję w ES5, będzie ona podobna do następującej:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
na pierwszy rzut oka ten kod wygląda ok. Ale co, jeśli będziemy musieli ogłosić gracza, który nie jest powiązany z żadną drużyną?
obecny kod zawodzi, jeśli zostawimy teamName
poza:
announcePlayer('Zell', 'Liew')// Zell Liew, undefined
jestem pewien, że undefined nie jest zespołem.
jeśli gracz nie jest powiązany, ogłoszenie Zell Liew, unaffiliated
miałoby większy sens niż Zell Liew, undefined
. Nie zgadzasz się?
aby uzyskać announcePlayer
aby ogłosić Zell Liew, unaffiliated
, jednym ze sposobów jest przekazanie unaffiliated
ciągu jako teamName
:
announcePlayer('Zell', 'Liew', 'unaffiliated')// Zell Liew, unaffiliated
chociaż to działa, możemy zrobić lepiej, refaktoryzując unaffiliated
do announcePlayer
, sprawdzając, czy teamName
jest zdefiniowana.
w wersji ES5 możesz zmienić kod na coś takiego:
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
lub, jeśli jesteś savvier z operatorami trójskładnikowymi, można było wybrać wersję terser:
function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated' console.log(firstName + ' ' + lastName + ', ' + team)}
W ES6, przy domyślnych parametrach, możemy dodać Znak równości (=
) za każdym razem, gdy zdefiniujemy parametr. Jeśli to zrobimy, ES6 automatycznie domyślnie ustawia tę wartość, gdy parametr jest niezdefiniowany.
więc w tym kodzie poniżej, gdy teamName
jest niezdefiniowany, domyślnie jest to 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
całkiem fajne, prawda? 🙂
jeszcze jedno. Jeśli chcesz wywołać wartość domyślną, możesz ręcznie przekazać undefined
. To ręczne przekazywanie undefined
pomaga, gdy domyślny parametr nie jest ostatnim argumentem funkcji.
announcePlayer('Zell', 'Liew', undefined)// Zell Liew, unaffiliated
to wszystko, co musisz wiedzieć o parametrach domyślnych. Jest to proste i bardzo przydatne 🙂
Destructuring
Destructuring jest wygodnym sposobem pobierania wartości z tablic i obiektów. Istnieją niewielkie różnice między destrukcyjną tablicą a obiektami, więc porozmawiajmy o nich osobno.
niszczenie obiektów
powiedzmy, że masz następujący obiekt:
const Zell = { firstName: 'Zell', lastName: 'Liew'}
aby uzyskać firstName
i lastName
z Zell
, musisz utworzyć dwie zmienne, a następnie przypisać każdą zmienną do wartości, w ten sposób:
let firstName = Zell.firstName // Zelllet lastName = Zell.lastName // Liew
dzięki destrukcji możesz tworzyć i przypisywać te zmienne za pomocą jednej linii kodu. Oto jak niszczysz obiekty:
let { firstName, lastName } = Zellconsole.log(firstName) // Zellconsole.log(lastName) // Liew
widzisz, co tu się stało? Dodając nawiasy klamrowe ({}
) podczas deklarowania zmiennych, mówimy JavaScript, aby utworzył wspomniane zmienne, a następnie przypisał odpowiednio Zell.firstName
do firstName
i Zell.lastName
do lastName
.
to jest to, co dzieje się pod maską:
// What you writelet { firstName, lastName } = Zell// ES6 does this automaticallylet firstName = Zell.firstNamelet lastName = Zell.lastName
teraz, jeśli nazwa zmiennej jest już użyta, nie możemy ponownie zadeklarować tej zmiennej (zwłaszcza jeśli używasz let
lub const
).
nie działa:
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
jeśli napotkasz sytuacje takie jak powyżej, możesz zmienić nazwy zmiennych podczas destrukcji dwukropkiem (:
).
W poniższym przykładzie tworzę zmienną courseName
i przypisuję do niej course.name
.
let { name: courseName } = courseconsole.log(courseName) // JS Fundamentals for Frontend Developers// What ES6 does under the hood:let courseName = course.name
jeszcze jedno.
nie martw się, jeśli spróbujesz zniszczyć zmienną, która nie jest zawarta w obiekcie. Po prostu powróci undefined
.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package } = courseconsole.log(package) // undefined
ale czekaj, to nie wszystko. Pamiętasz domyślne parametry?
możesz również zapisać domyślne parametry dla zniszczonych zmiennych. Składnia jest taka sama jak przy definiowaniu funkcji.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package = 'full course' } = courseconsole.log(package) // full course
możesz nawet zmieniać nazwy zmiennych, zapewniając jednocześnie wartości domyślne. Po prostu połącz te dwa. Na początku będzie to wyglądać trochę zabawnie, ale przyzwyczaisz się do tego, jeśli często go używasz:
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package: packageName = 'full course' } = courseconsole.log(packageName) // full course
to wszystko do niszczenia obiektów. Przejdźmy dalej i porozmawiajmy o destrukcji tablic 😄.
Tablice destrukcyjne
Tablice destrukcyjne i Obiekty destrukcyjne są podobne. Używamy nawiasów kwadratowych () zamiast nawiasów klamrowych (
{}
).
kiedy niszczysz tablicę,
- Twoja pierwsza zmienna jest pierwszym elementem tablicy.
- druga zmienna jest drugą pozycją w tablicy.
- i tak dalej…
let = console.log(one) // 1console.log(two) // 2
możliwe jest zniszczenie tak wielu zmiennych, że przekroczy się ilość pozycji w danej tablicy. Gdy tak się stanie, dodatkową zniszczoną zmienną będzie po prostu undefined
.
let = console.log(one) // 1console.log(two) // 2console.log(three) // undefined
niszcząc tablice, często niszczymy tylko te zmienne, których potrzebujemy. Jeśli potrzebujesz reszty tablicy, możesz użyć operatora rest (...
), w ten sposób:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93console.log(rest) //
więcej o operatorach rest omówimy w poniższej sekcji. Ale na razie porozmawiajmy o unikalnej zdolności, którą otrzymujesz dzięki zniszczonym tablicom-zamianie zmiennych.
Zamiana zmiennych ze zniszczonymi tablicami
powiedzmy, że masz dwie zmienne, a
i b
.
let a = 2let b = 3
chciałeś zamienić te zmienne. Więc a = 3
i b = 2
. W ES5, musisz użyć tymczasowej trzeciej zmiennej, aby zakończyć swap:
let a = 2let b = 3let temp// swappingtemp = a // temp is now 2a = b // a is now 3b = temp // b is now 2
chociaż to działa, logika może być rozmyta i myląca, zwłaszcza z wprowadzeniem trzeciej zmiennej.
teraz zobacz jak zrobisz to w sposób ES6 ze zniszczonymi tablicami:
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
💥💥💥. O wiele prostsze w porównaniu do poprzedniej metody zamiany zmiennych! 🙂
następnie porozmawiajmy o destrukcji tablic i obiektów w funkcji.
destrukcja tablic i obiektów podczas deklarowania funkcji
najfajniejszą rzeczą w destrukcji jest to, że możesz ich używać wszędzie. Dosłownie. Możesz nawet niszczyć obiekty i tablice w funkcjach.
powiedzmy, że mamy funkcję, która pobiera tablicę wyników i zwraca obiekt z trzema najlepszymi wynikami. Ta funkcja jest podobna do tego, co zrobiliśmy podczas niszczenia tablic.
// Note: You don't need arrow functions to use any other ES6 featuresfunction topThree (scores) { let = scores return { first: first, second: second, third: third }}
alternatywnym sposobem zapisu tej funkcji jest zniszczenie scores
podczas deklarowania funkcji. W tym przypadku jest o jedną linijkę kodu mniej do napisania. W tym samym czasie, wiemy, że bierzemy w tablicy.
function topThree () { return { first: first, second: second, third: third }}
Super fajne, prawda? 😄.
oto krótki quiz dla Ciebie. Ponieważ możemy łączyć domyślne parametry i destrukcję podczas deklarowania funkcji, co mówi poniżej?
function sayMyName ({ firstName = 'Zell', lastName = 'Liew'} = {}) { console.log(firstName + ' ' + lastName)}
to jest trudne. Łączymy ze sobą kilka funkcji.
po pierwsze, widzimy, że ta funkcja przyjmuje jeden argument, obiekt. Ten obiekt jest opcjonalny i domyślnie {}
, gdy jest niezdefiniowany.
Po Drugie, próbujemy zniszczyć zmienne firstName
i lastName
z danego obiektu. Jeśli te właściwości zostaną znalezione, użyj ich.
wreszcie, jeśli firstName
lub lastName
jest niezdefiniowany w danym obiekcie, ustawiamy go odpowiednio na Zell
i Liew
.
tak więc ta funkcja daje następujące wyniki:
sayMyName() // Zell LiewsayMyName({firstName: 'Zell'}) // Zell LiewsayMyName({firstName: 'Vincy', lastName: 'Zhang'}) // Vincy Zhang
całkiem fajnie połączyć destrukcję i domyślne parametry w deklaracji funkcji, co? 😄. Uwielbiam to.
następnie przyjrzyjmy się rest and spread.
parametr rest i operator spreadu
parametr rest i operator spreadu wyglądają tak samo. Oba są oznaczone trzema kropkami (...
).
to, co robią, jest różne w zależności od tego, do czego są używane. Dlatego nazywa się je inaczej. Spójrzmy więc na parametr rest i operator spreadu osobno.
parametr rest
luźno przetłumaczony, parametr rest oznacza, że weź resztę rzeczy i zapakuj ją do tablicy. Konwertuje rozdzieloną przecinkami listę argumentów na tablicę.
przyjrzyjmy się parametrowi rest w akcji. Wyobraźmy sobie, że mamy funkcję add
, która podsumowuje swoje argumenty:
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 55
W ES5 polegaliśmy na zmiennej arguments
, gdy mieliśmy do czynienia z funkcją, która przyjmuje nieznaną liczbę zmiennych. Ta arguments
zmienna jest podobna do tablicy Symbol
.
function sum () { console.log(arguments)}sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
jednym ze sposobów obliczenia tej sumy argumentów jest przekształcenie jej w tablicę z Array.prototype.slice.call(arguments)
, a następnie Pętla przez każdą liczbę za pomocą metody tablicy, takiej jak forEach
lub reduce
.
jestem pewien, że możesz zrobić forEach
sam, więc oto przykład reduce
:
// ES5 wayfunction sum () { let argsArray = Array.prototype.slice.call(arguments) return argsArray.reduce(function(sum, current) { return sum + current }, 0)}
z parametrem ES6 rest, możemy spakować wszystkie argumenty rozdzielane przecinkami prosto do tablicy.
// 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)}
dużo czystsze? 🙂.
teraz krótko napotkaliśmy parametr rest wcześniej w sekcji destrukcja. Tam, próbowaliśmy zniszczyć tablicę wyników do trzech najlepszych wyników:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93
jeśli chcemy resztę wyników, możemy to zrobić, pakując resztę wyników do tablicy z parametrem rest.
let scores = let = scoresconsole.log(restOfScores) //
jeśli kiedykolwiek będziesz zdezorientowany, pamiętaj o tym — parametr rest pakuje wszystko do tablicy. Pojawia się w parametrach funkcji i podczas destrukcji tablic.
następnie przejdźmy do spread.
Operator spreadu
Operator spreadu zachowuje się w przeciwny sposób w porównaniu z parametrem rest. Luźno mówiąc, pobiera tablicę i rozprzestrzenia ją (jak jam) na oddzieloną przecinkami listę argumentów.
let array = // These two are exactly the sameconsole.log(...array) // one two threeconsole.log('one', 'two', 'three') // one two three
Operator spread jest często używany do łączenia tablic w sposób łatwiejszy do odczytania i zrozumienia.
powiedzmy na przykład, że chcesz połączyć następujące tablice:
let array1 = let array2 = let array3 =
sposobem połączenia tych dwóch tablic ES5 jest użycie metody Array.concat
. Możesz połączyć wiele Array.concat
, aby połączyć dowolną liczbę tablic, w ten sposób:
// ES5 waylet combinedArray = array1.concat(array2).concat(array3)console.log(combinedArray) //
dzięki operatorowi rozprzestrzeniania ES6 możesz rozłożyć tablice na nową tablicę, taką jak ta, która jest nieco łatwiejsza do odczytania, gdy się do niej przyzwyczaisz:
// ES6 waylet combinedArray = console.log(combinedArray) //
Operator spread może być również użyty do usunięcia elementu z tablicy bez mutacji tablicy. Metoda ta jest powszechnie stosowana w Redux. Gorąco polecam obejrzenie tego filmu dana Abramova, jeśli chcesz zobaczyć, jak to działa.
to tyle dla spreadu:)
Rozszerzone literały obiektów
obiekty powinny być znajome, ponieważ piszesz JavaScript. Na wypadek, gdybyś o nich nie wiedział, wyglądają mniej więcej tak:
const anObject = { property1: 'value1', property2: 'value2', property3: 'value3',}
ES6 enhanced object literals przynosi trzy słodkie ulepszenia do obiektów, które znasz i kochasz. Są to:
- skróty wartości właściwości
- skróty metod
- możliwość używania obliczonych nazw właściwości
spójrzmy na każdą z nich. Obiecuję, że będzie szybko:)
skróty wartości właściwości
czy zauważyłeś, że czasami przypisujesz zmienną o tej samej nazwie co właściwość obiektu? Wiesz, coś w tym stylu.:
const fullName = 'Zell Liew'const Zell = { fullName: fullName}
cóż, nie chciałbyś napisać tego w krótszy sposób, ponieważ właściwość (fullName
) i wartość (fullName
)?
( o ty rozpieszczony Bachorze).
oto dobra wiadomość. Możesz! 🙂
ES6 poprawia obiekty o skróconej wartości właściwości. Oznacza to, że zmienna może być zapisana tylko wtedy, gdy nazwa zmiennej jest zgodna z nazwą właściwości. ES6 zajmie się resztą.
oto jak to wygląda:
const fullName = 'Zell Liew'// ES6 wayconst Zell = { fullName}// Underneath the hood, ES6 does this:const Zell = { fullName: fullName}
nieźle, co? Mamy mniej słów do napisania i wszyscy wracamy do domu szczęśliwi.
podczas gdy ja tańczę, proszę iść dalej i przejść do bardziej skróconej dobroci. Niedługo do was dołączę.
skróty metod
metody są funkcjami powiązanymi z właściwością. Są nazwane specjalnie dlatego, że są funkcjami:)
to jest przykład metody:
const anObject = { aMethod: function () { console.log("I'm a method!~~")}}
z ES6, dostajemy do pisania metod za pomocą skrótu. Możemy usunąć : function
z deklaracji metody i będzie ona działać tak, jak kiedyś:
const anObject = { // ES6 way aShorthandMethod (arg1, arg2) {}, // ES5 way aLonghandMethod: function (arg1, arg2) {},}
dzięki tej aktualizacji obiekty otrzymują już metodę skróconą, więc proszę nie używać funkcji strzałek podczas definiowania obiektów. Złamiesz kontekst this
(zobacz Funkcje strzałek, jeśli nie pamiętasz dlaczego).
const dontDoThis = { // Noooo. Don't do this arrowFunction: () => {}}
to wszystko ze skróconymi metodami obiektowymi. Przejdźmy do ostatecznego ulepszenia przedmiotów.
obliczone nazwy właściwości obiektów
czasami podczas tworzenia obiektów potrzebna jest nazwa właściwości dynamicznej. W Starym JavaScript sposób, musisz utworzyć obiekt, a następnie przypisać właściwość do in, w ten sposób:
// 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',// }
W ES6 nie musisz już tego robić. Dynamiczne nazwy właściwości można przypisać bezpośrednio podczas tworzenia obiektu. Kluczem jest zamknięcie właściwości dynamicznej nawiasami kwadratowymi:
const newPropertyName = 'smile'// ES6 way.const anObject = { aProperty: 'a value', // Dynamic property names! : ':D', : 'XD',}// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }
Schweeet! Prawda? 🙂
i tyle dla ulepszonych literałów obiektów. Nie mówiłem, że będzie szybko? 🙂
przejdźmy do kolejnej niesamowitej funkcji, którą absolutnie uwielbiam: literały szablonów.
literały szablonów
Obsługa ciągów w JavaScript jest niezwykle niezgrabnym doświadczeniem. Sam tego doświadczyłeś, gdy wcześniej utworzyliśmy funkcję announcePlayer
w parametrach domyślnych. Tam stworzyliśmy przestrzenie z pustymi ciągami i połączyliśmy je z plusami:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}
W ES6 ten problem znika dzięki literałom szablonów! (W specyfikacji były one wcześniej nazywane ciągami szablonów).
aby utworzyć dosłowny szablon w ES6, załączasz ciągi za pomocą backticks (`
). W backticks uzyskujesz dostęp do specjalnego symbolu zastępczego (${}
), w którym możesz normalnie używać JavaScript.
oto jak to wygląda w akcji:
const firstName = 'Zell'const lastName = 'Liew'const teamName = 'unaffiliated'const theString = `${firstName} ${lastName}, ${teamName}`console.log(theString)// Zell Liew, unaffiliated
widzisz? Możemy grupować wszystko za pomocą literałów szablonów! W literałach szablonów jest to angielski jak zwykle. Prawie tak, jakbyśmy używali silnika szablonów:)
najlepszą częścią literałów szablonów jest to, że można łatwo tworzyć Wielowierszowe ciągi znaków. To działa po wyjęciu z pudełka:
const multi = `One upon a time,In a land far far away,there lived a witich,who could change night into day`
jedną z fajnych sztuczek jest użycie tych ciągów do tworzenia elementów HTML w JavaScript, jeśli ich potrzebujesz. (Uwaga: Może to nie jest najlepszy sposób na tworzenie elementów HTML, ale nadal jest o wiele lepszy niż tworzenie ich jeden po drugim!).
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)
Zobacz pióro za pomocą wielowierszowych łańcuchów do tworzenia bardziej skomplikowanych elementów HTML przez Zell Liew (@zellwk) na CodePen.
Inną cechą literałów szablonów są tzw. znaczniki. Tagi są funkcjami, które pozwalają manipulować szablonem, jeśli chcesz zastąpić dowolny ciąg znaków.
oto jak to wygląda:
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}`
szczerze mówiąc, mimo że tagi szablonu wyglądają fajnie, nie miałem jeszcze dla nich zastosowania. Jeśli chcesz dowiedzieć się więcej o tagach szablonów, proponuję przeczytać ten odnośnik na MDN.
to tyle dla literałów szablonów.
Woo! To prawie wszystkie niesamowite funkcje ES6, których używam regularnie. ES6 jest super. Zdecydowanie warto poświęcić trochę czasu i dowiedzieć się o nich, abyś mógł zrozumieć, o czym piszą inni.