10th May 2017
JavaScript har utvecklats ett ton under de senaste åren. Om du lär dig JavaScript 2017 och inte har rört ES6 missar du ett enklare sätt att läsa och skriva JavaScript.
oroa dig inte om du inte är en mästare på JavaScript ännu. Du behöver inte vara fantastisk på JavaScript för att dra nytta av de extra bonusarna ES6 ger dig. I den här artikeln vill jag dela med dig åtta ES6-funktioner som jag använder dagligen som utvecklare för att hjälpa dig att underlätta den nya syntaxen.
- en lista över ES6-funktioner
- Let och const
- låt vs var
- låt vs const
- Pilfunktioner
- den nitty-gritty av arrow funktioner
- den lexikala detta
- standardparametrar
- Destructuring
- förstörande objekt
- Destructuring arrays
- byta variabler med förstörda arrayer
- Destructuring arrays och objekt medan du förklarar funktioner
- rest-parametern och spread-operatören
- Rest-parametern
- spridningsoperatören
- förbättrade objektbokstäver
- fastighetsvärde shorthands
- Method shorthands
- beräknade objektegenskapsnamn
- Mallbokstavar
- omslag upp
en lista över ES6-funktioner
först och främst är ES6 en enorm uppdatering till JavaScript. Här är en stor lista med funktioner om du är nyfiken på vad som är nytt, tack vare Luke Hoban:
- Pilar
- klasser
- förbättrade objektbokstavar
- mallsträngar
- Destructuring
- standard + vila + spridning
- låt + const
- iteratorer + för…av
- generatorer
- Unicode
- moduler
- modul lastare
- karta + set + weakmap + Weakset
- proxyservrar
- symboler
- underklassbara inbyggda ins
- löften
- Math + antal + sträng + array + objekt API: er
- binära och oktala bokstäver
- reflektera API
- svans samtal
låt inte den här stora listan med funktioner skrämma dig bort från ES6. Du behöver inte veta allt direkt. Jag kommer att dela med dig åtta av dessa funktioner som jag använder dagligen. De är:
- Let och const
- Pilfunktioner
- standardparametrar
- Destructuring
- Rest parameter och sprida operator
- förbättrade objektbokstäver
- Mallbokstäver
- löften
vi kommer att gå igenom de åtta funktionerna i följande avsnitt. För tillfället går jag igenom de första fem funktionerna. Jag lägger till resten när jag går med de närmaste veckorna.
förresten, webbläsarstöd för ES6 är fantastiskt. Nästan allt stöds inbyggt om du kodar för de senaste webbläsarna (Edge och senaste versionerna av FF, Chrome och Safari).
du behöver inte snygga verktyg som Webpack om du ville skriva ES6. Om webbläsarstöd saknas i ditt fall kan du alltid falla tillbaka på polyfills skapade av samhället. Bara google dem:)
med det, låt oss hoppa in i den första funktionen.
Let och const
i ES5 (det gamla JavaScript) är vi vana vid att förklara variabler med nyckelordet var
. I ES6 kan detta var
nyckelord ersättas med let
och const
, två kraftfulla nyckelord som gör utvecklingen enklare.
Låt oss först titta på skillnaden mellan let
och var
för att förstå varför let
och const
är bättre.
låt vs var
Låt oss prata om var
först eftersom vi är bekanta med det.
först och främst kan vi deklarera variabler med nyckelordet var
. En gång deklarerad kan denna variabel användas var som helst i det aktuella omfånget.
var me = 'Zell'console.log(me) // Zell
i exemplet ovan har jag förklarat me
som en global variabel. Denna globala me
– variabel kan också användas i en funktion, så här:
var me = 'Zell'function sayMe () { console.log(me)}sayMe() // Zell
det omvända är dock inte sant. Om jag deklarerar en variabel i en funktion kan jag inte använda den utanför funktionen.
function sayMe() { var me = 'Zell' console.log(me)}sayMe() // Zellconsole.log(me) // Uncaught ReferenceError: me is not defined
så, vi kan säga att var
är function-scoped. Det betyder att när en variabel skapas med var
i en funktion, kommer den bara att existera inom funktionen.
om variabeln skapas utanför funktionen finns den i det yttre omfånget.
var me = 'Zell' // global scopefunction sayMe () { var me = 'Sleepy head' // local scope console.log(me)}sayMe() // Sleepy headconsole.log(me) // Zell
let
, å andra sidan, är block-scoped. Det betyder att när en variabel skapas med let
, kommer den bara att existera inom sitt block.
men vänta, vad är ett block?
ett block i JavaScript är något inom ett par lockiga hängslen. Följande är exempel på block.
{ // new scope block}if (true) { // new scope block}while (true) { // new scope block}function () { // new block scope}
skillnaden mellan blockomfång och funktionsvariabler är enorm. När du använder en funktionsvariabel kan du av misstag skriva över en variabel utan att ha för avsikt att göra det. Här är ett exempel:
var me = 'Zell'if (true) { var me = 'Sleepy head'}console.log(me) // 'Sleepy head'
i det här exemplet kan du se att me
blir Sleepy head
efter att ha kört igenom if
– blocket. Det här exemplet kommer sannolikt inte att orsaka några problem för dig eftersom du förmodligen inte kommer att förklara variabler med samma namn.
men alla som arbetar med var
i en for
loop-situation kan stöta på lite konstighet på grund av hur variablerna är scoped. Tänk på följande kod som loggar variabeln i
fyra gånger och loggar sedan i
igen med en setTimeout
– funktion.
for (var i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
vad skulle du förvänta dig att den här koden skulle göra? Här är vad som faktiskt händer
hur heck gjorde i
bli 5
för fyra gånger inuti timeout-funktionen? Tja, visar sig, eftersom var
är funktion-scoped, värdet av i
blev 4
redan innan timeout-funktionen körs.
för att få rätt i
– värde inom setTimeout
, som körs senare, måste vi skapa en annan funktion, säg logLater
, för att säkerställa att i
– värdet inte ändras av for
– slingan innan setTimeout
körs:
function logLater (i) { setTimeout(function () { console.log(i) })}for (var i = 1; i < 5; i++) { console.log(i) logLater(i)};
(förresten kallas detta en stängning).
den goda nyheten är, function-scoped weirdness som for loop-exemplet som jag just har visat att du inte händer med let
. Samma timeout-exempel som vi har skrivit tidigare kan skrivas som detta, och det kommer att fungera direkt ur lådan utan att skriva ytterligare funktioner:
for (let i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
som du kan se gör block-scoped variabler utvecklingen mycket enklare genom att ta bort vanliga gotchas med funktionsvariabler. För att göra livet enkelt rekommenderar jag att du använder let
över var
när du deklarerar JavaScript-variabler från och med nu. (ES6 är den nya JavaScript redan Brasilien).
nu vet vi vad let
gör, låt oss gå vidare till skillnaden mellan let
och const
.
låt vs const
liksom let
, const
är också blockerad-scoped. Skillnaden är att const
inte kan omfördelas när den deklarerats.
const name = 'Zell'name = 'Sleepy head' // TypeError: Assignment to constant variable.let name1 = 'Zell'name1 = 'Sleepy head'console.log(name1) // 'Sleepy head'
eftersom const
inte kan omfördelas, är de bra för variabler skulle inte förändras.
låt oss säga att jag har en knapp som lanserar en modal på min hemsida. Jag vet att det bara kommer att finnas en knapp, och det skulle inte förändras. I det här fallet kan jag använda const
.
const modalLauncher = document.querySelector('.jsModalLauncher')
när jag förklarar variabler föredrar jag alltid const
över let
när det är möjligt eftersom jag får den extra cue som variabeln inte skulle bli omfördelad. Sedan använder jag let
för alla andra situationer.
låt oss sedan gå vidare och prata om pilfunktioner.
Pilfunktioner
Pilfunktioner betecknas med fat-pilen (=>
) som du ser överallt i ES6-koden. Det är en stenografi att göra anonyma funktioner. De kan användas var som helst function
nyckelordet används. Till exempel:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
Pilfunktioner är ganska coola. De hjälper till att göra koden kortare, vilket ger färre utrymme för fel att dölja. De hjälper dig också att skriva kod som är lättare att förstå när du vänjer dig vid syntaxen.
Låt oss dyka in i nitty-gritty av pilfunktioner så att du lär dig att känna igen och använda dem.
den nitty-gritty av arrow funktioner
först och främst, låt oss tala om att skapa funktioner. I JavaScript är du förmodligen van vid att skapa funktioner på detta sätt:
function namedFunction() { // Do something}// using the functionnamedFunction()
det finns en andra metod för att skapa funktioner. Du kan skapa en anonym funktion och tilldela den till en variabel. För att skapa en anonym funktion lämnar vi dess namn ur funktionsdeklarationen.
var namedFunction = function() { // Do something}
ett tredje sätt att skapa funktioner är att skapa dem direkt som ett argument till en annan funktion eller metod. Detta tredje användningsfall är det vanligaste för anonyma funktioner. Här är ett exempel:
// Using an anonymous function in a callbackbutton.addEventListener('click', function() { // Do something})
eftersom ES6 arrow-funktioner är stenografi för anonyma funktioner kan du ersätta arrow-funktioner var du än skapar en anonym funktion.
så här ser det ut:
// 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})
se likheten här? I grund och botten tar du bort sökordet function
och ersätter det med =>
på en något annorlunda plats.
men vad är det stora med pilfunktioner? Ersätter vi inte bara function
med =>
?
Tja, det visar sig att vi inte bara ersätter function
med =>
. En pilfunktions syntax kan ändras beroende på två faktorer:
- antalet argument som krävs
- om du vill ha en implicit avkastning.
den första faktorn är antalet argument som levereras till pilfunktionen. Om du bara anger ett argument kan du ta bort parentesen som omger argumenten. Om inga argument krävs kan du ersätta parentesen (()
) med ett understreck (_
).
alla följande är giltiga pilfunktioner.
const zeroArgs = () => {/* do something */}const zeroWithUnderscore = _ => {/* do something */}const oneArg = arg1 => {/* do something */}const oneArgWithParenthesis = (arg1) => {/* do something */}const manyArgs = (arg1, arg2) => {/* do something */}
den andra faktorn för pilfunktioner är om du vill ha en implicit retur. Pilfunktioner skapar som standard automatiskt ett return
– nyckelord om koden bara tar upp en rad och inte är innesluten i ett block.
så, dessa två är ekvivalenta:
const sum1 = (num1, num2) => num1 + num2const sum2 = (num1, num2) => { return num1 + num2 }
dessa två faktorer är anledningen till att du kan skriva kortare kod som moreThan20
du har sett ovan:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
Sammanfattningsvis är pilfunktionerna ganska coola. De tar lite tid att vänja sig, så ge det ett försök och du kommer att använda det överallt ganska snart.
men innan du hoppar på pilfunktionerna FTW bandwagon, vill jag låta dig veta om en annan nitty-gritty funktion av ES6 arrow – funktionen som orsakar mycket förvirring-den lexiska this
.
den lexikala detta
this
är ett unikt sökord vars värde ändras beroende på hur det kallas. När det kallas utanför någon funktion, this
standard Window
objektet i webbläsaren.
console.log(this) // Window
när this
anropas i ett enkelt funktionsanrop, är this
inställt på det globala objektet. När det gäller webbläsare kommer this
alltid att vara Window
.
function hello () { console.log(this)}hello() // Window
JavaScript ställer alltid in this
till fönsterobjektet i ett enkelt funktionsanrop. Detta förklarar varför värdet this
inom funktioner som setTimeout
alltid är Window
.
när this
anropas i en objektmetod skulle this
vara själva objektet:
let o = { sayThis: function() { console.log(this) }}o.sayThis() // o
när funktionen kallas som konstruktör hänvisar this
till det nybyggda objektet.
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
när den används i en händelse lyssnare, this
är inställd på det element som avfyrade händelsen.
let button = document.querySelector('button')button.addEventListener('click', function() { console.log(this) // button})
som du kan se i ovanstående situationer ställs värdet på this
in av den funktion som kallar den. Varje funktion definierar sin egen this
värde.
i fat arrow-funktioner blir this
aldrig bunden till ett nytt värde, oavsett hur funktionen kallas. this
kommer alltid att vara samma this
värde som dess omgivande kod. (Förresten, lexikala medel som hänför sig till, vilket jag antar, är hur den lexikala this
fick sitt namn).
okej, det låter förvirrande, så låt oss gå igenom några riktiga exempel.
först vill du aldrig använda pilfunktioner för att deklarera objektmetoder, eftersom du inte längre kan referera till objektet med 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 }}
för det andra kanske du inte vill använda pilfunktioner för att skapa händelselyssnare eftersom this
inte längre binder till det element du bifogade din händelselyssnare till.
men du kan alltid få rätt this
sammanhang med event.currentTarget
. Det är därför jag sa kanske inte.
button.addEventListener('click', function () { console.log(this) // button})button.addEventListener('click', e => { console.log(this) // Window console.log(event.currentTarget) // button})
för det tredje kanske du vill använda den lexikala this
på platser där this
– bindningen ändras utan att du vill ha det. Ett exempel är timeout-funktionen, så du behöver aldrig hantera this
, that
eller self
nonsens.
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) }}
detta användningsfall är särskilt användbart om du behöver lägga till eller ta bort en klass efter en tid har gått:
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) }}
slutligen, använd gärna fat arrow-funktionen någon annanstans för att göra din kod snyggare och kortare ,som exemplet moreThan20
som vi hade ovan:
let array = let moreThan20 = array.filter(num => num > 20)
Låt oss gå vidare.
standardparametrar
standardparametrar i ES6… ja, ger oss ett sätt att ange standardparametrar när vi definierar funktioner. Låt oss gå igenom ett exempel så ser du hur användbart det är.
låt oss säga att vi skapar en funktion som meddelar namnet på en spelare från ett lag. Om du skriver den här funktionen i ES5 kommer den att likna följande:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
vid första anblicken ser den här koden ok ut. Men vad händer om vi var tvungna att tillkännage en spelare som inte är kopplad till något lag?
den aktuella koden misslyckas pinsamt om vi lämnade teamName
ut:
announcePlayer('Zell', 'Liew')// Zell Liew, undefined
jag är ganska säker på att undefined inte är ett team av kakor.
om spelaren är unaffiliated, meddelar Zell Liew, unaffiliated
skulle vara mer meningsfullt att Zell Liew, undefined
. Håller du inte med?
för att få announcePlayer
att meddela Zell Liew, unaffiliated
, är vi ett sätt att skicka unaffiliated
strängen som teamName
:
announcePlayer('Zell', 'Liew', 'unaffiliated')// Zell Liew, unaffiliated
även om detta fungerar kan vi göra bättre genom att refactoring unaffiliated
till announcePlayer
genom att kontrollera om teamName
är definierad.
i ES5-versionen kan du refactor koden till något så här:
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
eller, om du är savvier med ternära operatörer, Du kunde ha valt en terser version:
function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated' console.log(firstName + ' ' + lastName + ', ' + team)}
i ES6, med standardparametrar, kan vi lägga till ett likhetstecken (=
) när vi definierar en parameter. Om vi gör det, ES6 automatiskt standardvärdet när parametern är odefinierad.
så, i den här koden nedan, när teamName
är odefinierad, är den som standard 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
ganska coolt, eller hur? 🙂
en sak till. Om du vill åberopa standardvärdet kan du skicka in undefined
manuellt. Den här handboken som går in på undefined
hjälper när din standardparameter inte är det sista argumentet för en funktion.
announcePlayer('Zell', 'Liew', undefined)// Zell Liew, unaffiliated
det är allt du behöver veta om standardparametrar. Det är enkelt och mycket användbart 🙂
Destructuring
Destructuring är ett bekvämt sätt att få värden ur arrayer och objekt. Det finns mindre skillnader mellan destructuring array och objekt, så låt oss prata om dem separat.
förstörande objekt
låt oss säga att du har följande objekt:
const Zell = { firstName: 'Zell', lastName: 'Liew'}
för att få firstName
och lastName
från Zell
måste du skapa två variabler och sedan tilldela varje variabel till ett värde, så här:
let firstName = Zell.firstName // Zelllet lastName = Zell.lastName // Liew
med destructuring kan du skapa och tilldela dessa variabler med en enda kodrad. Så här förstör du objekt:
let { firstName, lastName } = Zellconsole.log(firstName) // Zellconsole.log(lastName) // Liew
se vad som hände här? Genom att lägga till lockiga parenteser ({}
) medan vi förklarar variabler, berättar vi JavaScript för att skapa de ovannämnda variablerna, tilldela sedan Zell.firstName
till firstName
respektive Zell.lastName
till lastName
.
det här är vad som händer under huven:
// What you writelet { firstName, lastName } = Zell// ES6 does this automaticallylet firstName = Zell.firstNamelet lastName = Zell.lastName
om ett variabelnamn redan används kan vi inte deklarera variabeln igen (speciellt om du använder let
eller const
).
följande misslyckas med att fungera:
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
om du stöter på situationer som ovan kan du byta namn på variabler medan du förstör med ett kolon (:
).
i det här exemplet nedan skapar jag en courseName
variabel och tilldelar course.name
till den.
let { name: courseName } = courseconsole.log(courseName) // JS Fundamentals for Frontend Developers// What ES6 does under the hood:let courseName = course.name
en sak till.
oroa dig inte om du försöker förstöra en variabel som inte finns i ett objekt. Det kommer bara att återvända undefined
.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package } = courseconsole.log(package) // undefined
men vänta, det är inte allt. Kom ihåg standardparametrar?
Du kan också skriva standardparametrar för dina förstörda variabler. Syntaxen är densamma som när du definierar funktioner.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package = 'full course' } = courseconsole.log(package) // full course
Du kan även byta namn på variabler samtidigt som standardvärden. Bara kombinera de två. Det ser lite roligt ut i början, men du blir van vid det om du använder det ofta:
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package: packageName = 'full course' } = courseconsole.log(packageName) // full course
det är det för att förstöra föremål. Låt oss gå vidare och prata om destructuring arrays bisexuell.
Destructuring arrays
Destructuring arrays och destructuring objects är likartade. Vi använder fyrkantiga parenteser () istället för lockiga parenteser (
{}
).
när du förstör en array,
- din första variabel är det första objektet i matrisen.
- din andra variabel är det andra objektet i matrisen.
- och så vidare…
let = console.log(one) // 1console.log(two) // 2
det är möjligt att förstöra så många variabler att du överskrider antalet objekt i den givna matrisen. När detta händer kommer den extra förstörda variabeln bara att vara undefined
.
let = console.log(one) // 1console.log(two) // 2console.log(three) // undefined
vid destruktion av matriser förstör vi ofta bara de variabler vi behöver. Om du behöver resten av matrisen kan du använda rest-operatören (...
), så här:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93console.log(rest) //
vi pratar mer om vilooperatörer i följande avsnitt. Men för nu, låt oss prata om en unik förmåga du får med förstörda arrays – swapping variabler.
byta variabler med förstörda arrayer
låt oss säga att du har två variabler, a
och b
.
let a = 2let b = 3
du ville byta dessa variabler. Så a = 3
och b = 2
. I ES5 måste du använda en tillfällig tredje variabel för att slutföra bytet:
let a = 2let b = 3let temp// swappingtemp = a // temp is now 2a = b // a is now 3b = temp // b is now 2
även om detta fungerar kan logiken vara suddig och förvirrande, särskilt med införandet av en tredje variabel.
nu titta på hur du ska göra det ES6 sätt med förstörda matriser:
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
💥💥💥. Så mycket enklare jämfört med den tidigare metoden för att byta variabler! 🙂
låt oss sedan prata om förstörande arrayer och objekt i en funktion.
Destructuring arrays och objekt medan du förklarar funktioner
det coolaste med destructuring är att du kan använda dem var som helst. Bokstavligen. Du kan till och med Förstöra objekt och matriser i funktioner.
låt oss säga att vi har en funktion som tar in en rad poäng och returnerar ett objekt med de tre bästa poängen. Den här funktionen liknar vad vi har gjort när vi förstör arrayer.
// Note: You don't need arrow functions to use any other ES6 featuresfunction topThree (scores) { let = scores return { first: first, second: second, third: third }}
ett alternativt sätt att skriva denna funktion är att förstöra scores
medan du förklarar funktionen. I det här fallet finns det en mindre rad kod att skriva. Samtidigt vet vi att vi tar in en array.
function topThree () { return { first: first, second: second, third: third }}
supercool, eller hur? 😄.
nu, här är en snabb liten frågesport för dig. Eftersom vi kan kombinera standardparametrar och destruktion medan vi förklarar funktioner, vad säger följande?
function sayMyName ({ firstName = 'Zell', lastName = 'Liew'} = {}) { console.log(firstName + ' ' + lastName)}
detta är en knepig. Vi kombinerar några funktioner tillsammans.
först kan vi se att denna funktion tar in ett argument, ett objekt. Det här objektet är valfritt och är som standard {}
när det inte är definierat.
för det andra försöker vi förstöra firstName
och lastName
variabler från det givna objektet. Om dessa egenskaper hittas, använd dem.
slutligen, om firstName
eller lastName
är odefinierad i det givna objektet, ställer vi in det till Zell
respektive Liew
.
så, denna funktion ger följande resultat:
sayMyName() // Zell LiewsayMyName({firstName: 'Zell'}) // Zell LiewsayMyName({firstName: 'Vincy', lastName: 'Zhang'}) // Vincy Zhang
ganska coolt att kombinera destruktion och standardparametrar i en funktionsdeklaration eh? 😄. Jag älskar det här.
Låt oss sedan ta en titt på vila och sprida.
rest-parametern och spread-operatören
Rest-parametern och spread-operatören ser likadana ut. De är båda betecknade med tre punkter (...
).
vad de gör är olika beroende på vad de används för. Det är därför de heter annorlunda. Så, låt oss ta en titt på rest-parametern och sprida operatören separat.
Rest-parametern
löst översatt, rest-parametern betyder att ta resten av sakerna och packa den i en array. Den konverterar en kommaseparerad lista med argument till en array.
Låt oss ta en titt på rest-parametern i aktion. Föreställ dig att vi har en funktion, add
, som sammanfattar sina argument:
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 55
i ES5 berodde vi på variabeln arguments
när vi var tvungna att hantera en funktion som tar in ett okänt antal variabler. Denna arguments
variabel är en arrayliknande Symbol
.
function sum () { console.log(arguments)}sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
ett sätt att beräkna denna summa av argument är att konvertera den till en Array med Array.prototype.slice.call(arguments)
, sedan slinga genom varje nummer med en arraymetod som forEach
eller reduce
.
jag är säker på att du kan göra forEach
på egen hand, så här är reduce
exempel:
// ES5 wayfunction sum () { let argsArray = Array.prototype.slice.call(arguments) return argsArray.reduce(function(sum, current) { return sum + current }, 0)}
med ES6 rest-parametern kunde vi packa alla kommaseparerade argument rakt in i en array.
// 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)}
mycket renare? 🙂.
nu stötte vi kort på rest-parametern tidigare i destruktionssektionen. Där försökte vi förstöra en rad poäng i de tre bästa poängen:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93
om vi ville ha resten av poängen kunde vi göra det genom att packa resten av poängen i en array med rest-parametern.
let scores = let = scoresconsole.log(restOfScores) //
om du någonsin är förvirrad, kom bara ihåg det här — Rest-parametern packar allt i en array. Det visas i funktionsparametrar och under destruktion av arrayer.
Låt oss sedan gå vidare för att sprida.
spridningsoperatören
spridningsoperatören beter sig på motsatt sätt jämfört med rest-parametern. Löst uttryckt tar det en matris och sprider den (som sylt) i en kommaseparerad lista med argument.
let array = // These two are exactly the sameconsole.log(...array) // one two threeconsole.log('one', 'two', 'three') // one two three
spridningsoperatören används ofta för att hjälpa till att sammanfoga arrayer på ett sätt som är lättare att läsa och förstå.
Säg till exempel att du ville sammanfoga följande matriser:
let array1 = let array2 = let array3 =
ES5-sättet att sammanfoga dessa två arrayer är att använda Array.concat
– metoden. Du kan kedja Flera Array.concat
för att sammanfoga valfritt antal arrayer, så här:
// ES5 waylet combinedArray = array1.concat(array2).concat(array3)console.log(combinedArray) //
med ES6 spread operator kan du sprida arraysna till en ny array, så här, vilket är lite lättare att läsa när du blir van vid det:
// ES6 waylet combinedArray = console.log(combinedArray) //
spridningsoperatören kan också användas för att ta bort ett objekt från en array utan att mutera arrayen. Denna metod används ofta i Redux. Jag rekommenderar starkt att du tittar på den här videon av Dan Abramov om du är intresserad av att se hur det fungerar.
det är det för spridning 🙂
förbättrade objektbokstäver
objekt bör vara en bekant sak för dig eftersom du skriver JavaScript. Bara om du inte vet om dem ser de ut så här:
const anObject = { property1: 'value1', property2: 'value2', property3: 'value3',}
ES6 enhanced object literals ger tre söta uppgraderingar till de objekt du känner och älskar. De är:
- fastighetsvärde shorthands
- metod shorthands
- möjligheten att använda beräknade egenskapsnamn
Låt oss titta på var och en av dem. Jag lovar att det här kommer att bli snabbt:)
fastighetsvärde shorthands
har du märkt att du ibland tilldelar en variabel som har samma namn som en objektegenskap? Du vet, något så här:
const fullName = 'Zell Liew'const Zell = { fullName: fullName}
Tja, skulle du inte önska att du kunde skriva detta på ett kortare sätt, eftersom egenskapen (fullName
) och värdet (fullName
)?
(Åh, du förstörde brat bisexuell).
här är de goda nyheterna. Du kan! 🙂
ES6 förbättrar objekt med egenskapsvärde stenografi. Det betyder: Du kan bara skriva variabeln om ditt variabelnamn matchar ditt fastighetsnamn. ES6 tar hand om resten.
så här ser det ut:
const fullName = 'Zell Liew'// ES6 wayconst Zell = { fullName}// Underneath the hood, ES6 does this:const Zell = { fullName: fullName}
ganska snyggt, va? Nu har vi mindre ord att skriva, och vi går alla hem glada.
medan jag dansar, gå vidare och gå till mer stenografi godhet. Jag kommer snart.
Method shorthands
metoder är funktioner som är associerade med en egenskap. De heter bara speciellt eftersom de är funktioner 🙂
Detta är ett exempel på en metod:
const anObject = { aMethod: function () { console.log("I'm a method!~~")}}
med ES6 får vi skriva metoder med en stenografi. Vi kan ta bort : function
från en metoddeklaration och det kommer att fungera som det brukade:
const anObject = { // ES6 way aShorthandMethod (arg1, arg2) {}, // ES5 way aLonghandMethod: function (arg1, arg2) {},}
med den här uppgraderingen får objekt redan en stenografi, så snälla använd inte pilfunktioner när du definierar objekt. Du kommer att bryta this
– sammanhanget (se pilfunktioner om du inte kommer ihåg varför).
const dontDoThis = { // Noooo. Don't do this arrowFunction: () => {}}
det är det med object method shorthands. Låt oss gå vidare till den slutliga uppgraderingen vi får för objekt.
beräknade objektegenskapsnamn
ibland behöver du ett dynamiskt egenskapsnamn när du skapar objekt. På det gamla JavaScript-sättet måste du skapa objektet och sedan tilldela din egendom Till in, så här:
// 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',// }
i ES6 behöver du inte längre göra denna rondellväg. Du kan tilldela dynamiska egenskapsnamn direkt när du skapar ditt objekt. Nyckeln är att bifoga den dynamiska egenskapen med fyrkantiga parenteser:
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! Eller hur? 🙂
och det är det för förbättrade objektbokstäver. Sa jag inte att det går fort? 🙂
Låt oss gå vidare till en annan fantastisk funktion som jag absolut älskar: template literals.
Mallbokstavar
hantering av strängar i JavaScript är en extremt klumpig upplevelse. Du har upplevt det själv när vi skapade funktionen announcePlayer
tidigare i standardparametrar. Där skapade vi utrymmen med tomma strängar och gick med i dem med plusser:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}
i ES6 försvinner detta problem tack vare mallbokstäver! (I specifikationen kallades de tidigare mallsträngar).
för att skapa en mall bokstav i ES6, bifogar du strängar med backticks (`
). Inom backticks får du tillgång till en speciell platshållare (${}
) där du kan använda JavaScript normalt.
så här ser det ut i aktion:
const firstName = 'Zell'const lastName = 'Liew'const teamName = 'unaffiliated'const theString = `${firstName} ${lastName}, ${teamName}`console.log(theString)// Zell Liew, unaffiliated
ser du det? Vi kan gruppera allt med mallbokstäver! Inom mallbokstäver är det engelska som vanligt. Nästan som om vi använder en mallmotor:)
det bästa med mallbokstäver är att du enkelt kan skapa flera rader. Detta fungerar ur lådan:
const multi = `One upon a time,In a land far far away,there lived a witich,who could change night into day`
ett snyggt trick är att använda dessa strängar för att skapa HTML-element i JavaScript om du behöver dem. Det här kanske inte är det bästa sättet att göra HTML-element, men det är fortfarande bättre än att skapa dem en efter en!).
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)
se pennan med flerradiga strängar för att skapa mer komplicerade HTML-element av Zell Liew (@zellwk) på CodePen.
en annan funktion i mallbokstäver kallas taggar. Taggar är funktioner som låter dig manipulera mallen bokstavlig, om du vill ersätta någon sträng.
så här ser det ut:
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}`
för att vara ärlig, även om malltaggar ser coola ut, har jag inte haft ett användningsfall för dem ännu. Om du vill lära dig mer om malltaggar föreslår jag att du läser denna referens på MDN.
det är det för mallbokstäver.
omslag upp
Woo! Det är nästan alla fantastiska ES6-funktioner som jag använder regelbundet. ES6 är fantastiskt. Det är definitivt värt att ta lite tid och lära sig om dem, så att du kan förstå vad alla andra skriver om.