Parametri predefiniti in ES6
Quando scriviamo moduli, dobbiamo tenere conto dei casi in cui gli argomenti verranno omessi. In altre parole, i buoni moduli devono essere abbastanza intelligenti da avere valori predefiniti per i parametri. In ES5, dovresti scrivere qualcosa come il codice qui sotto, che usa il logico OR (||):
Queste istruzioni funzionano bene tranne che per i casi limite. Ad esempio, se il valore è 0 — e poiché 0 è falso in JavaScript — la condizione di default è il valore hard-coded invece di diventare il valore stesso, come si potrebbe desiderare in alcuni casi., Ovviamente, chi ha bisogno di 0 come valore (#sarcasmfont), quindi abbiamo semplicemente ignorato questo difetto e usato la logica O comunque
O forse event una condizione if/else per verificare il valore indefinito:
var getAccounts = function(limit) {
if (typeof limit == 'undefined') limit = 10
...
}
Non di più! In ES6, possiamo inserire i valori predefiniti nella firma delle funzioni in questo modo:
var getAccounts = function(limit = 10) {
...
}
var link = function(height = 50, color = 'red', url = 'http://capitalone.io') {
...
}
Questo non solo utilizza meno righe di codice, ma ha anche una maggiore leggibilità. A proposito, questa sintassi è simile a Ruby e Python!,
Rest and Spread Parameters in ES6
Se hai mai usato o scritto una funzione JavaScript con un numero variabile o addirittura illimitato di argomenti conosci l’oggetto argomento. Questo oggetto contiene tutti i parametri passati alla funzione. Il problema è che questo oggetto arguments non è un array reale. Devi convertirlo in un array se vuoi usare funzioni come sort o map esplicitamente. Ad esempio, questa funzione di richiesta converte gli argomenti usando call ():
Quindi c’è un modo migliore in ES6 per accedere a un numero indefinito di argomenti come array? Sì!, È la sintassi dei parametri rest ed è definita con ellissi …. Ad esempio, questa è la firma della funzione ES6 con i callback dei parametri rest che diventano un array con il resto dei parametri:
function(url, options, ...callbacks) {
var callback1 = callbacks
var callback2 = callbacks
// ...
}
Nota: Nell’array rest, il primo parametro è quello che non ha un nome, ad esempio, il callback è all’indice 0, non 2 come negli argomenti di ES5. Inoltre, inserire altri argomenti con nome dopo il parametro rest causerà un errore di sintassi. Il parametro rest è una grande aggiunta di sugarcoating a JavaScript poiché sostituisce l’oggetto arguments, che non era un vero array.,
In ES5, se si desidera utilizzare un array come argomento di una funzione, è necessario utilizzare l’applicazione() funzione:
function request(url, options, callback) {
// ...
}
var requestArgs =
request.apply(null, requestArgs)
Ora in ES6, possiamo usare la diffusione di parametri che hanno un aspetto simile a quello del resto dei parametri nella sintassi come si usano i puntini di sospensione…:
function request(url, options, callback) {
// ...
}
var requestArgs =
request(...requestArgs)
ES6 gli Sviluppatori possono utilizzare la diffusione dell’operatore nei seguenti casi:
La diffusione operatore ha una sintassi simile al resto dei parametri, ma il resto è utilizzato nella definizione della funzione/dichiarazione e diffusione è utilizzata nelle chiamate e letterali., Salvano gli sviluppatori dal digitare linee extra di codice imperativo, quindi conoscerli e usarli è una buona abilità.
I letterali del modello in ES6
i letterali del modello (o interpolazione come sono conosciuti in altre lingue) sono un modo per emettere variabili nella stringa mescolata con del testo, in genere nelle interfacce utente. In ES5, abbiamo dovuto rompere la corda in questo modo.,
var name = 'Your name is ' + first + ' ' + last + '.'
var url = 'http://localhost:3000/api/messages/' + id
Fortunatamente, in ES6 possiamo usare una nuova sintassi inside{NAME} all’interno della stringa back-ticked:
var name = `Your name is ${first} ${last}.`
var url = `http://localhost:3000/api/messages/${id}`
Questo è pulito e consente agli sviluppatori di vedere il risultato finale delle stringhe con una sola occhiata invece di provare a valutare l’espressione di concatenazione.
I modelli di stringa ES6 sono buoni, ma la sintassi causerà conflitti nella documentazione di Markdown se si utilizzano modelli di stringa e markup di codice in linea, (perché in Markdown il codice in linea è contrassegnato anche da back-tick)., A proposito, CoffeeScript ha quella che penso una soluzione migliore quando interpola stringhe a doppio quit (simile a Ruby):
var name = "Your name is #{first} #{last}."
var url = "http://localhost:3000/api/messages/#{id}"
L’interpolazione è buona, ma come lavori con il testo multilinea in JavaScript?
Stringhe multi-linea in ES6
Un altro sugarcoating sintattico yummy è stringa multi-linea. In ES5, abbiamo dovuto usare uno di questi approcci ed era brutto., Con concatenazione:
O con escape slash:
var fourAgreements = 'You have the right to be you.\n\
You can only be you when you do your best.'
Mentre in ES6, è sufficiente utilizzare i backtick come segue:
var roadPoem = `Then took the other, as just as fair,
And having perhaps the better claim
Because it was grassy and wanted wear,
Though as for that the passing there
Had worn them really about the same,`
var fourAgreements = `You have the right to be you.
You can only be you when you do your best.`
Le stringhe multilinea sono un’aggiunta utile se devi usare molto testo nel tuo codice JavaScript.,
Destrutturazione di Assegnazione in ES6
Destrutturazione può essere più difficile concetto di multi-linea stringhe perché c’è qualcosa di magico dietro le quinte… diciamo che hanno un semplice assegnazioni di cui chiavi userId e accountNumber sono variabili userId e accountNumber:
var data = $('body').data(), // data has properties
userId and accountNumber userId = data.userId, accountNumber = data.accountNumber
Altri esempi di lavori svolti dove ci sono i nomi delle variabili e le proprietà dell’oggetto sono le stesse:
In ES6, siamo in grado di sostituire il ES5 codice sopra con queste istruzioni:
var { userId, accountNumber} = $('body').data()
var {json} = require('body-parser')
var {username, password} = req.body
Questo funziona anche con le matrici. Pazzo!,
var = $('.column'),
= file.split('\n')
Potrebbe volerci del tempo per abituarsi alla sintassi di assegnazione destrutturante, ma è comunque un dolce sugarcoating.
Enhanced Object Literals in ES6
Quello che puoi fare con object literals in ES6 è strabiliante! Siamo passati da una versione glorificata di JSON in ES5 a qualcosa di strettamente simile alle classi in ES6.
Nello sviluppo aziendale, la modularizzazione del codice è importante perché i progetti sono più grandi e hanno un numero maggiore di parti mobili. Con i letterali degli oggetti avanzati, è possibile creare oggetti veramente forti caricati con funzionalità.,
Ecco un tipico oggetto letterale ES5 con alcuni metodi e attributi/proprietà:
Se vogliamo essere fantasiosi, possiamo ereditare da serviceBase rendendolo il prototipo con l’Oggetto.creare il metodo:
so, accountServiceES5ObjectCreate e accountServiceES5 NON sono totalmente identiche, perché un oggetto (accountServiceES5) avrà la proprietà del __proto__ oggetto, come mostrato nella figura di seguito:
Ma per il bene di questo esempio, prendiamo in considerazione il loro simile., Nei letterali degli oggetti ES6, possiamo usare le scorciatoie per l’assegnazione. Ad esempio, getAccounts: getAccounts, diventa solo getAccounts.
Inoltre, possiamo invocare super e avere chiavi dinamiche. Ad esempio, il metodo toString () restituisce un oggetto JSON come stringa chiamando super.valueOf () e valueOf_1_2_3 è un nome di proprietà dinamico:
Questo è un ottimo miglioramento per i buoni vecchi letterali di oggetti perché gli sviluppatori possono più cose che con gli oggetti ES5!,
Funzioni freccia in ES6
Questa è probabilmente la caratteristica che ho aspettato di più. Ho amato CoffeeScript per le sue frecce grasse. Ora li abbiamo in ES6.
Le frecce fat sono sorprendenti perché farebbero sì che questo si comporti correttamente, cioè, questo avrà lo stesso valore del contesto della funzione — non muterà come accade tipicamente ogni volta che crei una chiusura. Questo comportamento era una delle parti peggiori di JavaScript e spesso causava molta confusione con gli sviluppatori nuovi alla lingua., L’uso delle funzioni delle frecce in ES6 ci consente di smettere di usare that = this or self = this or _this = this or .bind (questo).
Ad esempio, questo codice in ES5 è brutto perché puoi dimenticare di trasferire il contesto alla chiusura con _this:
var _this = this
$('.btn').click(function(event){
_this.sendData()
})
Gli approcci bind() o call() non sono molto migliori a causa della loro verbosità. Ma dai un’occhiata a questo grazioso codice ES6:
$('.btn').click((event) =>{
this.sendData()
})
Purtroppo, il comitato ES6 ha deciso che prendere in prestito frecce magre da CoffeeScript era troppo una buona cosa e ci ha lasciato invece una lunga vecchia funzione., (Skinny arrow in CoffeeScript funziona come una funzione regolare in ES5 e ES6).
Ecco un altro esempio in cui usiamo call per passare il contesto alla funzione logUpperCase() in ES5:
Mentre in ES6, non abbiamo bisogno di scherzare con _this:
Nota che puoi combinare la vecchia funzione con => in ES6 come meglio credi. E quando una funzione freccia viene utilizzata con un’istruzione a una riga, diventa un’espressione; cioè,. restituirà implicitamente il risultato di quella singola istruzione. Se hai più di una riga, dovrai usare return esplicitamente.,
Questo codice ES5 sta creando un array dall’array dei messaggi:
Diventerà questo in ES6:
var ids =
var messages = ids.map(value => `ID is ${value}`) // implicit return
Si noti che ho usato i modelli di stringa? Un’altra caratteristica da CoffeeScript them li amo!
Le parentesi () sono opzionali per i singoli parametri in una firma della funzione freccia. Tuttavia, ne avrai bisogno quando usi più di un parametro. In ES5 il codice ha una funzione con ritorno esplicito:
Ora ecco una versione più eloquente del codice in ES6 con parentesi attorno ai parametri e ritorno implicito:
Le frecce fat non sono grandi? Usali.,
Promesse in ES6
Le promesse sono state un argomento di sviluppo controverso, specialmente nelle organizzazioni più grandi dove può essere più difficile concordare un approccio comune. Una ragione di ciò è il numero di implementazioni di promesse che utilizzano sintassi leggermente diverse: Q, bluebird, differita.js, vow, avow e jquery differiti per citarne solo alcuni. Un altro motivo è che alcuni ingegneri del software dicono: “Non abbiamo bisogno di promesse e possiamo semplicemente usare asincroni, generatori, callback, ecc.”
Fortunatamente, c’è una possibilità che i dibattiti si calmino con l’implementazione standard della promessa aggiunta a ES6!,
si consideri piuttosto banale esempio di un ritardo di esecuzione asincrona con setTimeout():
setTimeout(function(){ console.log('Yay!') }, 1000)
Siamo in grado di ri-scrivere questo codice in ES6 con una Promessa:
var wait1000 = new Promise(function(resolve, reject) {
setTimeout(resolve, 1000)
}).then(function() {
console.log('Yay!')
})
O con ES6 freccia funzioni:
var wait1000 = new Promise((resolve, reject)=> {
setTimeout(resolve, 1000)
}).then(()=> {
console.log('Yay!')
})
finora, abbiamo aumentato il numero di linee di codice da tre a cinque, senza alcun beneficio evidente. Esatto, sembra controintuitivo. Il vantaggio arriverà se abbiamo più logica annidata all’interno del callback setTimeout ()., Ad esempio, questo codice ES5 ha due callback nidificati:
setTimeout(function(){
console.log('Yay!')
setTimeout(function(){
console.log('Wheeyee!')
}, 1000)
}, 1000)
Può essere riscritto con le promesse ES6 in questo modo:
Come puoi osservare, l’organizzazione del codice è cambiata quando abbiamo rifattorizzato i callback-solo il codice in codice con le promesse.
Un altro vantaggio non coperto in questo saggio — le promesse hanno anche un callback fail-and-catch-all che è una bella caratteristica. Dai un’occhiata a questo post per maggiori informazioni sulle promesse: Introduzione alle promesse ES6.
Costrutti con ambito di blocco: Let e Const
Potresti aver già visto lo strano suono let nel codice ES6., Questa non è semplicemente una caratteristica sugarcoating. È più intricato e aggiunge più logica alle dichiarazioni delle variabili.
let è una nuova var che consente agli sviluppatori di scope la variabile ai blocchi. Definiamo i blocchi dalle parentesi graffe. In ES5, i blocchi non hanno fatto NULLA ai var come visto qui:
Nel codice sopra, il risultato sarà 1000. Wow! E ‘ davvero un brutto insetto. In ES6, usiamo let per limitare l’ambito ai blocchi. Vars sono quindi funzione ambito.
In questo codice, il valore è 0 perché il blocco if ha anche la dichiarazione let., Se non avesse nulla (importo=1), allora l’espressione sarebbe stata 1.
Quando si tratta di const, le cose sono più semplici; impedisce solo la riassegnazione, ed è anche con ambito di blocco come let. Solo per dimostrare, qui ci sono più costanti e il codice funziona bene perché le istruzioni const appartengono a blocchi diversi:
A mio modesto parere, let e const complicano eccessivamente il linguaggio. Senza di loro abbiamo avuto un solo comportamento, ora ci sono più scenari da considerare., ;- (Per le persone nuove a JavaScript, che provengono da linguaggi come Java, const e let offrono un nuovo livello di protezione integrata contro alcuni comportamenti imprevedibili.
Classi in ES6
Se amate la programmazione orientata agli oggetti (OOP), allora vi innamorerete di questa funzione. Rende la scrittura di classi in ES6, e ereditando da loro, facile come gradire un commento su Facebook.
In ES5, la creazione e l’utilizzo delle classi erano difficili da dire. Non c’era una classe di parole chiave (era riservata, ma non faceva nulla)., In aggiunta a ciò, un sacco di modelli di ereditarietà come pseudo classico, classico, funzionale aggiunto alla confusione, versando benzina sulle divisioni infuocate tra gli sviluppatori JavaScript.
Non ti mostrerò come scrivere una classe in ES5, perché ci sono molti pattern. Diamo subito un’occhiata all’esempio ES6. Posso dirti che la classe ES6 utilizzerà i prototipi, non l’approccio factory function. Abbiamo un classbaseModel in cui possiamo definire un costruttore e un metodo getName ():
Si noti che sto usando i valori dei parametri predefiniti per opzioni e dati., Inoltre, i nomi dei metodi non devono più avere la funzione word o i due punti (:). L’altra grande differenza è che non è possibile assegnare proprietà this.NAME allo stesso modo dei metodi, cioè, non puoi dire nome allo stesso livello di indentazione di un metodo. Per impostare il valore di una proprietà, è sufficiente assegnare un valore nel costruttore.,
Il AccountModel eredita baseModel con il NOME di classe si estende NOME_PADRE:
class AccountModel extends baseModel {
constructor(options, data) {
chiamare il padre costruttore, senza sforzo richiamare super() con parametri:
super({private: true}, ) // Call the parent method with super
this.name = 'Account Model'
this.url +='/accounts/'
}
Se vuoi essere davvero di fantasia, si può anche impostare un getter come questo con accountsData come una proprietà:
get accountsData() { // Calculated attribute getter
// ... make XHR
return this.data
}
}
Così, dopo tutto questo lavoro, come si fa a utilizzare questa classe abracadabra? E ‘ facile come ingannare un bambino di tre anni a credere in Babbo Natale., Usa il nuovo operando:
let accounts = new AccountModel(5)
accounts.getName()
console.log('Data is %s', accounts.accountsData)
Nel caso te lo stia chiedendo, l’output è:
Class name: Account Model
Data is %s 32113123123,524214691
Naturalmente, le classi esistevano in CoffeeScript e standard JavaScript precedenti, quindi non sono completamente nuove. Tuttavia, in ES6 l’utilizzo delle classi è stato reso più semplice, il che è particolarmente importante per gli sviluppatori aziendali perché in genere lavorano su progetti più grandi che abbracciano più team (quindi il codice richiede la modularizzazione).
Moduli in ES6
Come forse saprai, non c’era alcun supporto per moduli nativi in JavaScript prima di ES6., La gente si avvicinò con AMD, RequireJS, CommonJS e altre soluzioni alternative, ma erano proprio questo-soluzione e hack. Con ES6 ora ci sono moduli integrati con operandi di importazione ed esportazione.
In ES5, dovresti usare<script> tag con IIFE, o una libreria come AMD, mentre in ES6 puoi esporre la tua classe con export. Dal momento che sono un Nodo.js guy quindi userò CommonJS, che è anche un Nodo.sintassi js, per risolvere questo problema. È abbastanza semplice utilizzare CommonJS sul browser con il bundler Browserify., Diciamo che abbiamo la variabile di porta e il metodo getAccounts nel modulo ES5.js:
module.exports = {
port: 3000,
getAccounts: function() {
...
}
}
In ES5 principale.js, richiederemmo (‘modulo’) quella dipendenza:
var service = require('module.js')
console.log(service.port) // 3000
In ES6, useremmo l’esportazione e l’importazione. Ad esempio, questa è la nostra libreria nel modulo ES6.file js:
export var port = 3000
export function getAccounts(url) {
...
}
Nel file importer ES6 main.js, usiamo import {name} dalla sintassi ‘my-module’., Ad esempio, possiamo importare oggetti/metodi port e getAccounts dal modulo chiamato module:
import {port, getAccounts} from 'module'
console.log(port) // 3000
Oppure possiamo importare tutto come servizio variabile in main.js:
import * as service from 'module'
console.log(service.port) // 3000
Nota, che il supporto nativo per i moduli ES6 nei browser non arriverà presto (almeno al momento della stesura di questo articolo), quindi avrai bisogno di qualcosa come jspm per utilizzare i moduli ES6.
Per ulteriori informazioni ed esempi sui moduli ES6, date un’occhiata a questo testo. E ricorda, – non importa cosa, scrivi JavaScript modulare!,
Per…of Comprehensions in ES6
Ecco un problema con ES5: quando vogliamo iterare sugli oggetti usando le sue chiavi, dobbiamo estrarre prima quelle chiavi con Object.chiave(). Ad esempio:
Un altro problema con forEach è che è necessario scrivere la funzione word. Ma c’è una dichiarazione migliore in ES6! L’istruzione for of of sostituisce lo standard for e forEach ed è simile a for…in tranne quello for…in itera su chiavi e per values di oltre valori.,
Utilizzando il precedente frammento di codice dati (libri), siamo in grado di scorrere utilizzando per…e le chiavi o utilizzando per…di:
for (let key in books){
console.log(books)
}
Uscite le chiavi:
Pro Express.js
React Quickly
Full Stack JavaScript
Azat
Mentre per…di collaborerà con i valori:
for (let book of books){
console.log(book)
}
L’uscita di…di:
Pro Express.js
React Quickly
Full Stack JavaScript
si Noti che l’output di per…di ignora il valore con il tasto autore come sarebbe forEach su un array:
la Mia personale esperienza di lavoro con genericità è che aumentano la leggibilità del codice. Questo è fondamentale per la manutenzione del codice nelle applicazioni aziendali.