10 Mai 2017
JavaScript a progresat o tonă în ultimii ani. Dacă înveți JavaScript în 2017 și nu ai atins ES6, pierzi o modalitate mai ușoară de a citi și scrie JavaScript.
nu vă faceți griji dacă nu sunteți încă un master la JavaScript. Nu trebuie să fii minunat la JavaScript pentru a profita de bonusurile adăugate pe care le oferă ES6. În acest articol, vreau să vă împărtășesc opt caracteristici ES6 pe care le folosesc zilnic ca dezvoltator pentru a vă ajuta să vă ușurați noua sintaxă.
- o listă de caracteristici ES6
- Let și const
- să vs var
- să vs const
- funcțiile săgeții
- nitty-curajos de funcții săgeată
- lexicalul acest
- parametrii impliciți
- Destructuring
- destructurarea obiectelor
- destructuring arrays
- schimbarea variabilelor cu matrice destructurate
- destructurarea matricelor și obiectelor în timp ce declarați funcții
- parametrul rest și operatorul spread
- parametrul rest
- operatorul de răspândire
- enhanced obiect literals
- shorthands valoarea proprietății
- metoda shorthands
- nume de proprietate obiect calculat
- literali șablon
- împachetare
o listă de caracteristici ES6
în primul rând, ES6 este o actualizare uriașă pentru JavaScript. Iată o listă mare de caracteristici dacă sunteți curioși de noutățile, datorită lui Luke Hoban:
- săgeți
- clase
- literale obiect îmbunătățite
- șiruri șablon
- destructurare
- Default + rest + spread
- să + const
- iteratori + pentru…de
- generatoare
- Unicode
- module
- Încărcătoare de module
- map + set + weakmap + Weakset
- proxy-uri
- simboluri
- încorporate Subclasabile
- promisiuni
- matematică + număr + șir + matrice + API-uri obiect
- literale binare și octale
- reflectă API
- Coadă apeluri
nu lăsați această listă mare de caracteristici să vă sperie de ES6. Nu trebuie să știi totul imediat. Am de gând să împărtășesc cu voi opt dintre aceste caracteristici pe care le folosesc pe o bază de zi cu zi. Acestea sunt:
- să și const
- funcții săgeată
- parametrii implicite
- Destructuring
- parametru de repaus și operatorul răspândirea
- literali obiect îmbunătățite
- literali șablon
- promisiuni
vom parcurgeți cele opt caracteristici din secțiunile următoare. Pentru moment, voi trece prin primele cinci caracteristici. Voi adăuga restul ca voi merge de-a lungul în următoarele două săptămâni.
apropo, suportul browserului pentru ES6 este uimitor. Aproape totul este acceptat nativ dacă codificați cele mai recente browsere (Edge și cele mai recente versiuni ale FF, Chrome și Safari).
nu aveți nevoie de scule fanteziste precum Webpack dacă doriți să scrieți ES6. Dacă suportul browserului lipsește în cazul dvs., puteți oricând să reveniți la polyfills create de comunitate. Doar google-le 🙂
cu asta, să sari în prima caracteristică.
Let și const
în ES5 (vechiul JavaScript), suntem obișnuiți să declarăm variabile cu cuvântul cheie var
. În ES6, acest cuvânt cheie var
poate fi înlocuit cu let
și const
, două cuvinte cheie puternice care simplifică dezvoltarea.
Să analizăm mai întâi diferența dintre let
și var
pentru a înțelege de ce let
și const
sunt mai bune.
să vs var
să vorbim despre var
în primul rând, deoarece suntem familiarizați cu ea.
În primul rând, putem declara variabile cu cuvântul cheie var
. Odată declarată, această variabilă poate fi utilizată oriunde în domeniul actual.
var me = 'Zell'console.log(me) // Zell
în exemplul de mai sus, am declarat me
ca variabilă globală. Această variabilă globală me
poate fi utilizată și într-o funcție, ca aceasta:
var me = 'Zell'function sayMe () { console.log(me)}sayMe() // Zell
cu toate acestea, inversul nu este adevărat. Dacă declar o variabilă într-o funcție, nu o pot folosi în afara funcției.
function sayMe() { var me = 'Zell' console.log(me)}sayMe() // Zellconsole.log(me) // Uncaught ReferenceError: me is not defined
Deci, putem spune că var
este funcția scoped. Aceasta înseamnă că ori de câte ori o variabilă este creată cu var
într-o funcție, aceasta va exista numai în cadrul funcției.
dacă variabila este creată în afara funcției, aceasta va exista în domeniul exterior.
var me = 'Zell' // global scopefunction sayMe () { var me = 'Sleepy head' // local scope console.log(me)}sayMe() // Sleepy headconsole.log(me) // Zell
let
, pe de altă parte, este bloc-scoped. Aceasta înseamnă că ori de câte ori o variabilă este creată cu let
, va exista doar în blocul său.
dar stai, ce este un bloc?
un bloc în JavaScript este ceva într-o pereche de acolade buclat. Următoarele sunt exemple de blocuri.
{ // new scope block}if (true) { // new scope block}while (true) { // new scope block}function () { // new block scope}
diferența dintre variabilele bloc-scope și funcția-scoped sunt uriașe. Când utilizați o variabilă cu scop funcțional, puteți suprascrie accidental o variabilă fără a intenționa să faceți acest lucru. Iată un exemplu:
var me = 'Zell'if (true) { var me = 'Sleepy head'}console.log(me) // 'Sleepy head'
în acest exemplu, puteți vedea că me
devine Sleepy head
după ce treceți prin blocul if
. Acest exemplu nu vă va cauza probleme, deoarece probabil că nu veți declara variabile cu același nume.
dar oricine lucrează cu var
într-o situație de buclă for
poate intra într-o oarecare ciudățenie din cauza modului în care variabilele sunt vizate. Luați în considerare următorul cod care înregistrează variabila i
de patru ori, apoi înregistrează i
din nou cu o funcție setTimeout
.
for (var i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
ce v-ați aștepta să facă acest cod? Iată ce se întâmplă de fapt
cum naiba a devenit i
5
de patru ori în interiorul funcției timeout? Ei bine, se pare, pentru că var
este funcție scoped, valoarea i
a devenit 4
chiar înainte de funcția timeout rulează.
pentru a obține valoarea i
corectă în setTimeout
, care se execută mai târziu, trebuie să creăm o altă funcție, să zicem logLater
, pentru a ne asigura că valoarea i
nu se modifică de bucla for
înainte ca setTimeout
să execute:
function logLater (i) { setTimeout(function () { console.log(i) })}for (var i = 1; i < 5; i++) { console.log(i) logLater(i)};
(apropo, aceasta se numește închidere).
vestea bună este că ciudățenia cu scop funcțional, cum ar fi exemplul pentru buclă pe care tocmai vi l-am arătat, nu se întâmplă cu let
. Același exemplu timeout pe care l-am scris mai devreme ar putea fi scris ca acesta și va funcționa chiar din cutie fără a scrie funcții suplimentare:
for (let i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
după cum puteți vedea, variabilele cu scop bloc fac dezvoltarea mult mai simplă prin eliminarea Gotcha-urilor comune cu variabile cu scop funcțional. Pentru a face viața simplă, vă recomand să utilizați let
peste var
ori de câte ori declarați variabile JavaScript de acum înainte. (ES6 este noul JavaScript deja circulant).
acum știm ce face let
, să trecem la diferența dintre let
și const
.
să vs const
ca let
, const
este, de asemenea, blocat-scoped. Diferența este că const
nu poate fi realocat odată declarat.
const name = 'Zell'name = 'Sleepy head' // TypeError: Assignment to constant variable.let name1 = 'Zell'name1 = 'Sleepy head'console.log(name1) // 'Sleepy head'
deoarece const
nu poate fi realocat, sunt bune pentru variabile nu s-ar schimba.
să presupunem că am un buton care lansează un modal pe site-ul meu. Știu că va exista un singur buton și nu s-ar schimba. În acest caz, pot folosi const
.
const modalLauncher = document.querySelector('.jsModalLauncher')
la declararea variabilelor, prefer întotdeauna const
peste let
ori de câte ori este posibil, deoarece primesc semnalul suplimentar că variabila nu va fi reatribuită. Apoi, folosesc let
pentru toate celelalte situații.
în continuare, să mergem mai departe și să vorbim despre funcțiile săgeții.
funcțiile săgeții
funcțiile săgeții sunt notate cu săgeata grasă (=>
) pe care o vedeți peste tot în codul ES6. Este o prescurtare pentru a face funcții anonime. Ele pot fi folosite oriunde se utilizează cuvântul cheie function
. De exemplu:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
funcțiile săgeată sunt destul de cool. Ele ajută la scurtarea codului, ceea ce oferă mai puțin spațiu pentru ascunderea erorilor. De asemenea, vă ajută să scrieți cod care este mai ușor de înțeles odată ce vă obișnuiți cu sintaxa.
să se arunca cu capul în nitty-curajos de funcții săgeată, astfel încât să învețe să recunoască și să le utilizeze.
nitty-curajos de funcții săgeată
în primul rând, să vorbim despre crearea de funcții. În JavaScript, probabil că sunteți obișnuiți să creați funcții în acest fel:
function namedFunction() { // Do something}// using the functionnamedFunction()
există o a doua metodă de a crea funcții. Puteți crea o funcție anonimă și o puteți atribui unei variabile. Pentru a crea o funcție anonimă, lăsăm numele acesteia în afara declarației funcției.
var namedFunction = function() { // Do something}
o a treia modalitate de a crea funcții este de a le crea direct ca argument pentru o altă funcție sau metodă. Acest al treilea caz de utilizare este cel mai frecvent pentru funcțiile anonime. Iată un exemplu:
// Using an anonymous function in a callbackbutton.addEventListener('click', function() { // Do something})
deoarece funcțiile săgeată ES6 sunt prescurtare pentru funcții anonime, puteți înlocui funcțiile săgeată oriunde creați o funcție anonimă.
Iată cum arată:
// 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})
vezi asemănarea de aici? Practic, eliminați cuvântul cheie function
și îl înlocuiți cu =>
într-o locație ușor diferită.
dar ce mare lucru cu funcțiile săgeată? Nu înlocuim function
cu =>
?
Ei bine, se pare că nu înlocuim doar function
cu =>
. Sintaxa unei funcții săgeată se poate modifica în funcție de doi factori:
- numărul de argumente necesare
- dacă doriți o întoarcere implicită.
primul factor este numărul de argumente furnizate funcției săgeată. Dacă furnizați un singur argument, puteți elimina paranteza care înconjoară argumentele. Dacă nu sunt necesare argumente, puteți înlocui paranteza (()
) cu o subliniere (_
).
Toate următoarele sunt funcții săgeată valide.
const zeroArgs = () => {/* do something */}const zeroWithUnderscore = _ => {/* do something */}const oneArg = arg1 => {/* do something */}const oneArgWithParenthesis = (arg1) => {/* do something */}const manyArgs = (arg1, arg2) => {/* do something */}
al doilea factor pentru funcțiile săgeată este dacă doriți o întoarcere implicită. Funcțiile săgeată, în mod implicit, creează automat un cuvânt cheie return
dacă codul ocupă doar o singură linie și nu este inclus într-un bloc.
deci, aceste două sunt echivalente:
const sum1 = (num1, num2) => num1 + num2const sum2 = (num1, num2) => { return num1 + num2 }
acești doi factori sunt motivul pentru care puteți scrie cod mai scurt ca moreThan20
pe care l-ați văzut mai sus:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
pe scurt, funcțiile săgeată sunt destul de cool. Ei au nevoie de un pic de timp pentru a se obișnui, așa că încercați și îl veți folosi peste tot destul de curând.
dar înainte de a sări pe funcțiile săgeată FTW bandwagon, vreau să vă anunț despre o altă caracteristică nitty-curajos a funcției săgeată ES6 care provoacă o mulțime de confuzie – lexical this
.
lexicalul acest
this
este un cuvânt cheie unic a cărui valoare se schimbă în funcție de modul în care este numit. Când este apelat în afara oricărei funcții, this
implicit la Window
obiect în browser.
console.log(this) // Window
când this
este apelat într-un apel de funcție simplă, this
este setat la obiectul global. În cazul browserelor, this
va fi întotdeauna Window
.
function hello () { console.log(this)}hello() // Window
JavaScript setează întotdeauna this
la obiectul ferestrei într-un simplu apel de funcții. Aceasta explică de ce valoarea this
din funcții precum setTimeout
este întotdeauna Window
.
când this
este apelat într-o metodă obiect, this
ar fi obiectul în sine:
let o = { sayThis: function() { console.log(this) }}o.sayThis() // o
când funcția este numită constructor, this
se referă la obiectul nou construit.
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
când este utilizat într-un ascultător de evenimente, this
este setat la elementul care a declanșat evenimentul.
let button = document.querySelector('button')button.addEventListener('click', function() { console.log(this) // button})
după cum puteți vedea în situațiile de mai sus, valoarea this
este setată de funcția care o numește. Fiecare funcție definește propria valoare this
.
în funcțiile săgeată grasă, this
nu se leagă niciodată de o nouă valoare, indiferent de modul în care este apelată funcția. this
va fi întotdeauna aceeași valoare this
ca și codul său înconjurător. (Apropo, mijloacele lexicale referitoare la, ceea ce cred, este modul în care lexicalul this
și-a primit numele).
bine, sună confuz, așa că să trecem prin câteva exemple reale.
În primul rând, nu doriți să utilizați funcțiile săgeată pentru a declara metode obiect, pentru că nu se poate face referire obiectul cu this
mai.
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 }}
În al doilea rând, este posibil să nu doriți să utilizați funcțiile săgeată pentru a crea ascultători de evenimente, deoarece this
nu se mai leagă de elementul pe care l-ați atașat ascultătorului de evenimente.
cu toate acestea, puteți obține întotdeauna contextul this
potrivit cu event.currentTarget
. De aceea am spus că nu.
button.addEventListener('click', function () { console.log(this) // button})button.addEventListener('click', e => { console.log(this) // Window console.log(event.currentTarget) // button})
În al treilea rând, poate doriți să utilizați lexicalul this
în locurile în care legarea this
se schimbă fără să doriți. Un exemplu este funcția timeout, deci nu trebuie să vă ocupați niciodată de prostiile this
, that
sau 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) }}
acest caz de utilizare este deosebit de util dacă trebuie să adăugați sau să eliminați o clasă după ce a trecut ceva timp:
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) }}
în cele din urmă, nu ezitați să utilizați funcția săgeată grasă oriunde altundeva pentru a vă ajuta să vă faceți Codul mai ordonat și mai scurt, cum ar fi exemplul moreThan20
pe care l-am avut mai sus:
let array = let moreThan20 = array.filter(num => num > 20)
să mergem mai departe.
parametrii impliciți
parametrii impliciți în ES6… Ei bine, ne oferă o modalitate de a specifica parametrii impliciți atunci când definim funcții. Să trecem printr-un exemplu și veți vedea cât de util este.
să presupunem că creăm o funcție care anunță numele unui jucător dintr-o echipă. Dacă scrieți această funcție în ES5, va fi similară cu următoarea:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
la prima vedere, acest cod pare ok. Dar dacă ar trebui să anunțăm un jucător care nu este afiliat cu nicio echipă?
codul curent eșuează jenant dacă am plecat teamName
afară:
announcePlayer('Zell', 'Liew')// Zell Liew, undefined
sunt destul de sigur că undefined nu e o echipă.
dacă jucătorul nu este afiliat, anunțarea Zell Liew, unaffiliated
ar avea mai mult sens ca Zell Liew, undefined
. Nu ești de acord?
pentru a obține announcePlayer
pentru a anunța Zell Liew, unaffiliated
, am o modalitate este de a trece unaffiliated
șir ca teamName
:
announcePlayer('Zell', 'Liew', 'unaffiliated')// Zell Liew, unaffiliated
deși acest lucru funcționează, putem face mai bine prin refactorizarea unaffiliated
în announcePlayer
verificând dacă teamName
este definit.
în versiunea ES5, puteți refactor codul la ceva de genul asta:
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
sau, dacă sunteți savvier cu operatorii ternari, ați fi putut alege o versiune terser:
function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated' console.log(firstName + ' ' + lastName + ', ' + team)}
în ES6, cu parametrii impliciți, putem adăuga un semn egal (=
) ori de câte ori definim un parametru. Dacă facem acest lucru, ES6 implicit automat la acea valoare atunci când parametrul este nedefinit.
Deci, în acest cod de mai jos, atunci când teamName
este nedefinit, implicit 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
destul de cool, nu-i așa? 🙂
încă un lucru. Dacă doriți să invocați valoarea implicită, puteți trece manual undefined
. Acest manual de trecere în undefined
ajută atunci când parametrul implicit nu este ultimul argument al unei funcții.
announcePlayer('Zell', 'Liew', undefined)// Zell Liew, unaffiliated
asta e tot ce trebuie să știți despre parametrii implicite. Este simplu și foarte util 🙂
Destructuring
Destructuring este un mod convenabil de a obține valori din matrice și obiecte. Există diferențe minore între matricea de distrugere și obiecte, așa că hai să vorbim despre ele separat.
destructurarea obiectelor
să presupunem că aveți următorul obiect:
const Zell = { firstName: 'Zell', lastName: 'Liew'}
pentru a obține firstName
și lastName
de la Zell
, a trebuit să creați două variabile, apoi să atribuiți fiecare variabilă unei valori, astfel:
let firstName = Zell.firstName // Zelllet lastName = Zell.lastName // Liew
cu destructuring, puteți crea și atribui aceste variabile cu o singură linie de cod. Iată cum distrugeți obiectele:
let { firstName, lastName } = Zellconsole.log(firstName) // Zellconsole.log(lastName) // Liew
vezi ce s-a întâmplat aici? Prin adăugarea de paranteze buclat ({}
) în timp ce declararea variabile, suntem spune JavaScript pentru a crea variabilele menționate mai sus, apoi atribui Zell.firstName
la firstName
și Zell.lastName
la lastName
respectiv.
asta se întâmplă sub capotă:
// What you writelet { firstName, lastName } = Zell// ES6 does this automaticallylet firstName = Zell.firstNamelet lastName = Zell.lastName
acum, dacă un nume de variabilă este deja utilizat, Nu putem declara din nou variabila (mai ales dacă utilizați let
sau const
).
următoarele nu funcționează:
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
Dacă întâmpinați situații precum cele de mai sus, puteți redenumi variabilele în timp ce distrugeți cu două puncte (:
).
în acest exemplu de mai jos, creez o variabilă courseName
și îi atribuie course.name
.
let { name: courseName } = courseconsole.log(courseName) // JS Fundamentals for Frontend Developers// What ES6 does under the hood:let courseName = course.name
încă un lucru.
nu vă faceți griji dacă încercați să destructurați o variabilă care nu este conținută într-un obiect. Se va întoarce doar undefined
.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package } = courseconsole.log(package) // undefined
dar stai, asta nu e tot. Amintiți-vă parametrii impliciți?
puteți scrie parametrii implicite pentru variabilele destructurate, de asemenea. Sintaxa este aceeași ca atunci când definiți funcții.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package = 'full course' } = courseconsole.log(package) // full course
puteți redenumi chiar variabile în timp ce furnizarea de valori implicite. Doar combinați cele două. Va arăta puțin amuzant la început, dar te vei obișnui dacă îl folosești des:
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package: packageName = 'full course' } = courseconsole.log(packageName) // full course
asta e pentru distrugerea obiectelor. Să mergem mai departe și să vorbim despre destructuring array-uri.
destructuring arrays
destructuring arrays și destructuring obiecte sunt similare. Folosim paranteze pătrate () în loc de paranteze ondulate (
{}
).
când destructurați o matrice,
- prima dvs. variabilă este primul element din matrice.
- a doua variabilă este al doilea element din matrice.
- și așa mai departe…
let = console.log(one) // 1console.log(two) // 2
este posibil să distrugeți atât de multe variabile încât să depășiți numărul de elemente din matricea dată. Când se întâmplă acest lucru, variabila extra destructurată va fi doar undefined
.
let = console.log(one) // 1console.log(two) // 2console.log(three) // undefined
când distrugem matrice, deseori distrugem doar variabilele de care avem nevoie. Dacă aveți nevoie de restul matricei, puteți utiliza operatorul rest (...
), astfel:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93console.log(rest) //
vom vorbi mai multe despre operatorii rest în secțiunea următoare. Dar, deocamdată, să vorbim despre o abilitate unică pe care o obțineți cu matrice destructurate – schimbarea variabilelor.
schimbarea variabilelor cu matrice destructurate
să presupunem că aveți două variabile, a
și b
.
let a = 2let b = 3
ați vrut să schimbați aceste variabile. Deci a = 3
și b = 2
. În ES5, trebuie să utilizați o a treia variabilă temporară pentru a finaliza swap-ul:
let a = 2let b = 3let temp// swappingtemp = a // temp is now 2a = b // a is now 3b = temp // b is now 2
deși acest lucru funcționează, logica poate fi neclară și confuză, mai ales cu introducerea unei a treia variabile.
Acum urmăriți cum o veți face în modul ES6 cu matrice destructurate:
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
💥💥💥. Atât de mult mai simplu în comparație cu metoda anterioară de schimbare a variabilelor! 🙂
în continuare, să vorbim despre destructurarea matricelor și obiectelor într-o funcție.
destructurarea matricelor și obiectelor în timp ce declarați funcții
cel mai tare lucru despre destructurare este că le puteți folosi oriunde. Literalmente. Puteți chiar destructura obiecte și matrice în funcții.
să presupunem că avem o funcție care ia într-o serie de scoruri și returnează un obiect cu primele trei scoruri. Această funcție este similară cu ceea ce am făcut în timp ce destructuring matrice.
// Note: You don't need arrow functions to use any other ES6 featuresfunction topThree (scores) { let = scores return { first: first, second: second, third: third }}
o modalitate alternativă de a scrie această funcție este de a destructura scores
în timp ce declarați funcția. În acest caz, există o linie mai puțin de cod pentru a scrie. În același timp, știm că luăm o matrice.
function topThree () { return { first: first, second: second, third: third }}
Super tare, nu-i așa? 😄.
acum, iată un mic test rapid pentru tine. Deoarece putem combina parametrii impliciți și destructurarea în timp ce declarăm funcții, ce spun următoarele?
function sayMyName ({ firstName = 'Zell', lastName = 'Liew'} = {}) { console.log(firstName + ' ' + lastName)}
acesta este unul dificil. Combinăm câteva caracteristici împreună.
În primul rând, putem vedea că această funcție ia într-un argument, un obiect. Acest obiect este opțional și implicit la {}
atunci când nedefinit.
În al doilea rând, încercăm să distrugem variabilele firstName
și lastName
din obiectul dat. Dacă se găsesc aceste proprietăți, utilizați-le.
în cele din urmă, dacă firstName
sau lastName
este nedefinit în obiectul dat, îl setăm la Zell
și respectiv Liew
.
deci, această funcție produce următoarele rezultate:
sayMyName() // Zell LiewsayMyName({firstName: 'Zell'}) // Zell LiewsayMyName({firstName: 'Vincy', lastName: 'Zhang'}) // Vincy Zhang
destul de cool pentru a combina parametrii destructuring și implicit într-o declarație funcție nu-i așa? 😄. Îmi place asta.
apoi, să aruncăm o privire la odihnă și răspândire.
parametrul rest și operatorul spread
parametrul rest și operatorul spread arată la fel. Ambele sunt semnificate cu trei puncte (...
).
ceea ce fac este diferit în funcție de ceea ce sunt folosite. De aceea sunt numiți diferit. Deci, să aruncăm o privire la parametrul rest și să răspândim separat operatorul.
parametrul rest
tradus vag, parametrul rest înseamnă să luați restul lucrurilor și să le împachetați într-o matrice. Convertește o listă de argumente separate prin virgulă într-o matrice.
să aruncăm o privire la parametrul rest în acțiune. Imaginați-vă că avem o funcție, add
, care rezumă argumentele sale:
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 55
în ES5, depindeam de variabila arguments
ori de câte ori trebuia să avem de-a face cu o funcție care preia un număr necunoscut de variabile. Această variabilă arguments
este o matrice asemănătoare Symbol
.
function sum () { console.log(arguments)}sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
o modalitate de a calcula această sumă de argumente este de a converti într-o matrice cu Array.prototype.slice.call(arguments)
, apoi, bucla prin fiecare număr cu o metodă matrice ca forEach
sau reduce
.
sunt sigur că puteți face forEach
pe cont propriu, deci iată exemplul reduce
:
// ES5 wayfunction sum () { let argsArray = Array.prototype.slice.call(arguments) return argsArray.reduce(function(sum, current) { return sum + current }, 0)}
cu parametrul rest ES6, am putea împacheta toate argumentele separate prin virgulă direct într-o matrice.
// 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)}
mult mai curat? 🙂.
acum, am întâlnit pe scurt parametrul rest mai devreme în secțiunea destructuring. Acolo, am încercat să destructure o serie de scoruri în primele trei scoruri:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93
dacă am dori restul scorurilor, am putea face acest lucru prin ambalarea restului scorurilor într-o matrice cu parametrul rest.
let scores = let = scoresconsole.log(restOfScores) //
dacă sunteți vreodată confuz, amintiți — vă doar acest lucru-parametrul rest împachetează totul într-o matrice. Apare în parametrii funcției și în timp ce destructuring matrice.
în continuare, să trecem la răspândire.
operatorul de răspândire
operatorul de răspândire se comportă în mod opus în comparație cu parametrul rest. Vag pus, este nevoie de o matrice și se răspândește (cum ar fi gem) într-o listă separată prin virgulă de argumente.
let array = // These two are exactly the sameconsole.log(...array) // one two threeconsole.log('one', 'two', 'three') // one two three
operatorul de răspândire este adesea folosit pentru a ajuta la concatenarea matricelor într-un mod mai ușor de citit și de înțeles.
spune, de exemplu, ai vrut să concateneze următoarele matrice:
let array1 = let array2 = let array3 =
modul ES5 de concatenare a acestor două matrice este de a utiliza metoda Array.concat
. Puteți înlănțui mai multe Array.concat
pentru a concatena orice număr de matrice, astfel:
// ES5 waylet combinedArray = array1.concat(array2).concat(array3)console.log(combinedArray) //
cu ES6 spread operator, ai putea răspândi matrice într-o nouă matrice, ca aceasta, care este ușor mai ușor de citit odată ce te obișnuiești cu ea:
// ES6 waylet combinedArray = console.log(combinedArray) //
operatorul de răspândire poate fi, de asemenea, utilizat pentru a elimina un element dintr-o matrice fără a muta matricea. Această metodă este frecvent utilizată în Redux. Vă recomand să vizionați acest videoclip de Dan Abramov dacă sunteți interesat să vedeți cum funcționează.
asta e Pentru spread:)
enhanced obiect literals
obiecte ar trebui să fie un lucru familiar pentru tine, deoarece sunteți scris JavaScript. Doar în cazul în care nu știți despre ele, arată cam așa:
const anObject = { property1: 'value1', property2: 'value2', property3: 'value3',}
ES6 enhanced object literals aduce trei upgrade-uri dulci obiectelor pe care le cunoașteți și le iubiți. Acestea sunt:
- shorthands valoare proprietate
- metoda shorthands
- capacitatea de a utiliza nume de proprietate calculate
să ne uităm la fiecare dintre ele. Promit acest lucru va fi rapid:)
shorthands valoarea proprietății
ați observat că uneori atribuiți o variabilă care are același nume ca o proprietate obiect? Știi, ceva de genul asta:
const fullName = 'Zell Liew'const Zell = { fullName: fullName}
Ei bine, nu ați dori să puteți scrie acest lucru într-un mod mai scurt, deoarece proprietatea (fullName
) și valoarea (fullName
)?
(Oh, ai rasfatat brat inktiv).
iată vestea bună. Poți! 🙂
ES6 îmbunătățește obiecte cu valoare de proprietate shorthands. Aceasta înseamnă: puteți scrie numai variabila dacă numele variabilei se potrivește cu numele proprietății. ES6 se ocupă de restul.
Iată cum arată:
const fullName = 'Zell Liew'// ES6 wayconst Zell = { fullName}// Underneath the hood, ES6 does this:const Zell = { fullName: fullName}
destul de elegant, nu-i așa? Acum, avem mai puține cuvinte de scris și mergem cu toții fericiți acasă.
în timp ce dansez, vă rog să mergeți mai departe și să treceți la mai multă bunătate. Vin și eu imediat.
metoda shorthands
metodele sunt funcții care sunt asociate cu o proprietate. Sunt numiți special pentru că sunt funcții:)
acesta este un exemplu de metodă:
const anObject = { aMethod: function () { console.log("I'm a method!~~")}}
cu ES6, ajungem să scriem metode cu o stenografie. Putem elimina : function
dintr-o declarație de metodă și va funcționa ca înainte:
const anObject = { // ES6 way aShorthandMethod (arg1, arg2) {}, // ES5 way aLonghandMethod: function (arg1, arg2) {},}
cu această actualizare, obiectele primesc deja o metodă de stenografie, așa că vă rugăm să nu utilizați funcțiile săgeată atunci când definiți obiecte. Veți rupe contextul this
(consultați funcțiile săgeată dacă nu vă amintiți de ce).
const dontDoThis = { // Noooo. Don't do this arrowFunction: () => {}}
asta e cu metoda obiect shorthands. Să trecem la actualizarea finală pe care o obținem pentru obiecte.
nume de proprietate obiect calculat
uneori aveți nevoie de un nume de proprietate dinamic atunci când creați obiecte. În vechiul mod JavaScript, va trebui să creați obiectul, apoi să atribuiți proprietatea dvs. în, astfel:
// 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',// }
în ES6, nu mai trebuie să faceți acest sens giratoriu. Puteți atribui nume de proprietăți dinamice direct atunci când creați obiectul. Cheia este de a închide proprietatea dinamică cu paranteze pătrate:
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! Nu-i așa? 🙂
și asta este pentru literali obiect îmbunătățite. Nu am spus că va fi rapid? 🙂
să trecem la o altă caracteristică minunat Îmi place absolut: literali șablon.
literali șablon
siruri de caractere de manipulare în JavaScript este o experiență extrem de greoaie. Ați experimentat – o singur când am creat funcția announcePlayer
anterior în parametrii impliciți. Acolo, am creat spații cu șiruri goale și le-am alăturat cu plusuri:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}
în ES6, această problemă dispare datorită literali șablon! (În caietul de sarcini, acestea au fost numite anterior siruri de caractere șablon).
pentru a crea un șablon literal în ES6, anexați siruri de caractere cu backsticks (`
). În backsticks, aveți acces la un substituent special (${}
) unde puteți utiliza JavaScript în mod normal.
Iată cum arată în acțiune:
const firstName = 'Zell'const lastName = 'Liew'const teamName = 'unaffiliated'const theString = `${firstName} ${lastName}, ${teamName}`console.log(theString)// Zell Liew, unaffiliated
vezi asta? Putem grupa totul cu literali șablon! În cadrul literali șablon, este limba engleză ca de obicei. Aproape ca și cum am folosi un motor șablon:)
cea mai bună parte despre literali șablon este că puteți crea siruri de caractere multi-line cu ușurință. Acest lucru funcționează din cutie:
const multi = `One upon a time,In a land far far away,there lived a witich,who could change night into day`
un truc elegant este de a utiliza aceste siruri de caractere pentru a crea elemente HTML în JavaScript, dacă aveți nevoie de ele. (Notă: Acest lucru nu poate fi cel mai bun mod de a face elemente HTML, dar ei încă mult mai bine decât crearea lor unul câte unul!).
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)
vedeți stiloul folosind șiruri cu mai multe linii pentru a crea elemente HTML mai complicate de Zell Liew (@zellwk) pe CodePen.
o altă caracteristică a literalelor șablon se numește etichete. Etichetele sunt funcții care vă permit să manipulați șablonul literal, dacă doriți să înlocuiți orice șir.
Iată cum arată:
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}`
pentru a fi sincer, chiar dacă etichetele șabloanelor arată cool, nu am avut încă un caz de utilizare pentru ele. Dacă doriți să aflați mai multe despre etichetele șabloanelor, vă sugerez să citiți această referință pe MDN.
asta e pentru literali șablon.
împachetare
Woo! Asta e aproape toate caracteristicile ES6 minunat folosesc în mod regulat. ES6 este minunat. Cu siguranță merită să vă luați puțin timp și să aflați despre ele, astfel încât să puteți înțelege despre ce scriu toți ceilalți.