? Der komplette Handbuch ist jetzt bei Amazon erhältlich

let , const und blockieren Scoping let Ihnen Erstellen von Deklarationen erstellen, die an einen beliebigen Block gebunden sind, der als Block Scoping bezeichnet wird. Anstatt var zu verwenden, das Funktionsumfang bietet, wird empfohlen, Block -Scoped -Variablen ( let oder const ) in ES6 zu verwenden.
var a = 2 ;
{
let a = 3 ;
console . log ( a ) ; // 3
let a = 5 ; // TypeError: Identifier 'a' has already been declared
}
console . log ( a ) ; // 2 Eine andere Form der blockgeschützten Deklaration ist die const , die Konstanten erzeugt. In ES6 repräsentiert eine const eine konstante Referenz auf einen Wert. Mit anderen Worten, die Inhalte von Object und Array können sich ändern, wird nur die Neuzuweisung der Variablen verhindert. Hier ist ein einfaches Beispiel:
{
const b = 5 ;
b = 10 ; // TypeError: Assignment to constant variable
const arr = [ 5 , 6 ] ;
arr . push ( 7 ) ;
console . log ( arr ) ; // [5,6,7]
arr = 10 ; // TypeError: Assignment to constant variable
arr [ 0 ] = 3 ; // value is mutable
console . log ( arr ) ; // [3,6,7]
}Ein paar Dinge, die Sie beachten sollten:
let und const variiert von der traditionellen Hebezeuge von Variablen und Funktionen. Sowohl let als auch const werden gehoben, können aber aufgrund der zeitlichen Totenzone nicht vor ihrer Erklärung zugegriffen werdenlet und const werden zum nächsten blockierten Block geschrieben.const PI = 3.14 )const muss mit seiner Erklärung definiert werden.const Over let , es sei denn, Sie planen, die Variable neu zu ordnen. Pfeilfunktionen sind eine Kurznotation für das Schreiben von Funktionen in ES6. Die Pfeilfunktionsdefinition besteht aus einer Parameterliste ( ... ) , gefolgt von der => Marker und einem Funktionskörper. Für Einzelargumentfunktionen können die Klammern weggelassen werden.
// Classical Function Expression
function addition ( a , b ) {
return a + b ;
} ;
// Implementation with arrow function
const addition = ( a , b ) => a + b ;
// With single argument, no parentheses required
const add5 = a => 5 + a ; Beachten Sie, dass im obigen Beispiel die addition -Pfeilfunktion mit "prägnantem Körper" implementiert wird, für die keine explizite Rückgabeanweisung erforderlich ist. Beachten Sie den weggelassenen { } nach der => .
Hier ist ein Beispiel mit dem üblichen "Blockkörper". Einschließlich der lockigen Klammerverpackungen.
const arr = [ 'apple' , 'banana' , 'orange' ] ;
const breakfast = arr . map ( fruit => {
return fruit + 's' ;
} ) ;
console . log ( breakfast ) ; // ['apples', 'bananas', 'oranges']Sehen! Es gibt mehr ...
Pfeilfunktionen machen den Code nicht nur kürzer. Sie sind eng mit this Bindungsverhalten verwandt.
Das Verhalten des Pfeilfunktions mit this Schlüsselwort hängt von denen der normalen Funktionen ab. Jede Funktion in JavaScript definiert ihren eigenen this Kontext, aber Pfeilfunktionen erfassen this Wert des nächstgelegenen umschließenden Kontextes. Schauen Sie sich den folgenden Code an:
function Person ( ) {
// The Person() constructor defines `this` as an instance of itself.
this . age = 0 ;
setInterval ( function growUp ( ) {
// In non-strict mode, the growUp() function defines `this`
// as the global object, which is different from the `this`
// defined by the Person() constructor.
this . age ++ ;
} , 1000 ) ;
}
var p = new Person ( ) ; In ECMascript 3/5 wurde dieses Problem behoben, indem der Wert this einer Variablen zugewiesen wurde, die überschritten werden konnte.
function Person ( ) {
const self = this ;
self . age = 0 ;
setInterval ( function growUp ( ) {
// The callback refers to the `self` variable of which
// the value is the expected object.
self . age ++ ;
} , 1000 ) ;
}Wie oben erwähnt, erfassen die Pfeilfunktionen den Wert des nächstgelegenen umschließenden Kontextes, sodass der folgende Code auch bei verschachtelten Pfeilfunktionen wie erwartet funktioniert.
function Person ( ) {
this . age = 0 ;
setInterval ( ( ) => {
setTimeout ( ( ) => {
this . age ++ ; // `this` properly refers to the person object
} , 1000 ) ;
} , 1000 ) ;
}
let p = new Person ( ) ;Lesen Sie hier in Pfeilfunktionen mehr über "lexikalisch this" in Pfeilfunktionen
Mit ES6 können Sie Standardparameter in Funktionsdefinitionen festlegen. Hier ist eine einfache Illustration.
const getFinalPrice = ( price , tax = 0.7 ) => price + price * tax ;
getFinalPrice ( 500 ) ; // 850 ... Der Bediener wird als Spread- oder Rastoperator bezeichnet, je nachdem, wie und wo es verwendet wird.
Wenn es mit iterabler verwendet wird, wirkt es, dass es in einzelne Elemente "verbreitet" wird:
const makeToast = ( breadType , topping1 , topping2 ) => {
return `I had ${ breadType } toast with ${ topping1 } and ${ topping2 } ` ;
} ; const ingredients = [ 'wheat' , 'butter' , 'jam' ] ;
makeToast ( ... ingredients ) ;
// "I had wheat toast with butter and jam"
makeToast ( ... [ 'sourdough' , 'avocado' , 'kale' ] ) ;
// "I had sourdough toast with avocado and kale"Spread eignet sich auch hervorragend für die Gestaltung eines neuen Objekts aus anderen Objekten:
const defaults = { avatar : 'placeholder.jpg' , active : false }
const userData = { username : 'foo' , avatar : 'bar.jpg' }
console . log ( { created : '2017-12-31' , ... defaults , ... userData } )
// {created: "2017-12-31", avatar: "bar.jpg", active: false, username: "foo"}Neue Arrays können auch exprimiert geformt werden:
const arr1 = [ 1 , 2 , 3 ] ;
const arr2 = [ 7 , 8 , 9 ] ;
console . log ( [ ... arr1 , 4 , 5 , 6 , ... arr2 ] ) // [1, 2, 3, 4, 5, 6, 7, 8, 9] Die andere häufige Verwendung von ... ist es, alle Argumente in ein Array zu sammeln. Dies wird als "REST" -Berator bezeichnet.
function foo ( ... args ) {
console . log ( args ) ;
}
foo ( 1 , 2 , 3 , 4 , 5 ) ; // [1, 2, 3, 4, 5]ES6 ermöglicht das Deklarieren von Objektliteralen durch Bereitstellung einer Kurzsyntax für die Initialisierung von Eigenschaften aus Variablen und Definieren von Funktionsmethoden. Es ermöglicht auch die Möglichkeit, Eigenschaftsschlüssel in einer Objektliteraldefinition berechnet zu haben.
function getCar ( make , model , value ) {
return {
// with property value shorthand
// syntax, you can omit the property
// value if key matches variable
// name
make , // same as make: make
model , // same as model: model
value , // same as value: value
// computed values now work with
// object literals
[ 'make' + make ] : true ,
// Method definition shorthand syntax
// omits `function` keyword & colon
depreciate ( ) {
this . value -= 2500 ;
}
} ;
}
let car = getCar ( 'Kia' , 'Sorento' , 40000 ) ;
console . log ( car ) ;
// {
// make: 'Kia',
// model:'Sorento',
// value: 40000,
// makeKia: true,
// depreciate: function()
// } ES6 hat eine neue Unterstützung für Oktal- und Binärliterale. Die Vorbereitung einer Zahl mit 0o oder 0O würde sie in den Oktalwert umwandeln. Schauen Sie sich den folgenden Code an:
let oValue = 0o10 ;
console . log ( oValue ) ; // 8
let bValue = 0b10 ; // 0b or 0B for binary
console . log ( bValue ) ; // 2Die Zerstörung hilft bei der Vermeidung der Notwendigkeit von Tempor -Variablen beim Umgang mit Objekten und Arrays.
function foo ( ) {
return [ 1 , 2 , 3 ] ;
}
let arr = foo ( ) ; // [1,2,3]
let [ a , b , c ] = foo ( ) ;
console . log ( a , b , c ) ; // 1 2 3 function getCar ( ) {
return {
make : 'Tesla' ,
model : 'g95' ,
metadata : {
vin : '123abc' ,
miles : '12000'
}
} ;
}
const { make , model } = getCar ( ) ;
console . log ( make , model ) ; // Tesla g95
const { make , metadata : { miles } } = getCar ( ) ;
console . log ( make , miles ) ; // Tesla 12000
ES6 ermöglicht die Verwendung von super in (klassenlosen) Objekten mit Prototypen. Im Folgenden finden Sie ein einfaches Beispiel:
const parent = {
foo ( ) {
console . log ( "Hello from the Parent" ) ;
}
}
const child = {
foo ( ) {
super . foo ( ) ;
console . log ( "Hello from the Child" ) ;
}
}
Object . setPrototypeOf ( child , parent ) ;
child . foo ( ) ; // Hello from the Parent
// Hello from the ChildES6 führt eine einfachere Möglichkeit ein, Interpolationen hinzuzufügen, die automatisch bewertet werden.
`${ ... }` wird verwendet, um die Variablen zu rendern.` Backtick wird als Trennzeichen verwendet. let user = 'Kevin' ;
console . log ( `Hi ${ user } !` ) ; // Hi Kevin!for...of Iteraten über iterable Objekte wie Array. const nicknames = [ 'di' , 'boo' , 'punkeye' ] ;
nicknames . size = 3 ;
for ( let nickname of nicknames ) {
console . log ( nickname ) ;
}
// di
// boo
// punkeyefor...in Iteraten über alle aufzählbaren Eigenschaften eines Objekts. const nicknames = [ 'di' , 'boo' , 'punkeye' ] ;
nicknames . size = 3 ;
for ( let nickname in nicknames ) {
console . log ( nickname ) ;
}
// 0
// 1
// 2
// size ES6 führt einen neuen Satz von Datenstrukturen ein, die Map und WeakMap bezeichnen. Jetzt verwenden wir die ganze Zeit Karten in JavaScript. Tatsächlich kann jedes Objekt als Map betrachtet werden.
Ein Objekt besteht aus Tasten (immer Zeichenfolgen) und Werten, während in Map jeder Wert (sowohl Objekte als auch primitive Werte) entweder als Schlüssel oder als Wert verwendet werden kann. Schauen Sie sich diesen Code an:
const myMap = new Map ( ) ;
const keyString = "a string" ,
keyObj = { } ,
keyFunc = ( ) => { } ;
// setting the values
myMap . set ( keyString , "value associated with 'a string'" ) ;
myMap . set ( keyObj , "value associated with keyObj" ) ;
myMap . set ( keyFunc , "value associated with keyFunc" ) ;
myMap . size ; // 3
// getting the values
myMap . get ( keyString ) ; // "value associated with 'a string'"
myMap . get ( keyObj ) ; // "value associated with keyObj"
myMap . get ( keyFunc ) ; // "value associated with keyFunc"Schwäche
Auf eine WeakMap ist eine Karte, auf der die Schlüssel schwach referenziert werden, auf die nicht verhindert, dass ihre Schlüssel garbarby gesammelt werden. Das heißt, Sie müssen sich keine Sorgen um Speicherlecks machen.
Eine andere Sache, die hier in WeakMap zu beachten ist, anstatt jeden Schlüssel Map muss ein Objekt sein.
In einem WeakMap wird nur vier Methoden delete(key) , has(key) , get(key) und set(key, value) .
const w = new WeakMap ( ) ;
w . set ( 'a' , 'b' ) ;
// Uncaught TypeError: Invalid value used as weak map key
const o1 = { } ,
o2 = ( ) => { } ,
o3 = window ;
w . set ( o1 , 37 ) ;
w . set ( o2 , "azerty" ) ;
w . set ( o3 , undefined ) ;
w . get ( o3 ) ; // undefined, because that is the set value
w . has ( o1 ) ; // true
w . delete ( o1 ) ;
w . has ( o1 ) ; // falseSetze Objekte sind Sammlungen einzigartiger Werte. Doppelte Werte werden ignoriert, da die Sammlung alle eindeutigen Werte haben muss. Die Werte können primitive Typen oder Objektreferenzen sein.
const mySet = new Set ( [ 1 , 1 , 2 , 2 , 3 , 3 ] ) ;
mySet . size ; // 3
mySet . has ( 1 ) ; // true
mySet . add ( 'strings' ) ;
mySet . add ( { a : 1 , b : 2 } ) ; Sie können über einen Satz durch Einfügungsreihenfolge entweder mit der forEach -Methode oder der for...of Schleife iterieren.
mySet . forEach ( ( item ) => {
console . log ( item ) ;
// 1
// 2
// 3
// 'strings'
// Object { a: 1, b: 2 }
} ) ;
for ( let value of mySet ) {
console . log ( value ) ;
// 1
// 2
// 3
// 'strings'
// Object { a: 1, b: 2 }
} Sets haben auch die Methoden delete() und clear() .
Schwachset
Ähnlich wie bei WeakMap können Sie mit dem WeakSet -Objekt schwach gehaltene Objekte in einer Sammlung speichern. Ein Objekt in der WeakSet tritt nur einmal auf; Es ist einzigartig in der Sammlung von WeaPset.
const ws = new WeakSet ( ) ;
const obj = { } ;
const foo = { } ;
ws . add ( window ) ;
ws . add ( obj ) ;
ws . has ( window ) ; // true
ws . has ( foo ) ; // false, foo has not been added to the set
ws . delete ( window ) ; // removes window from the set
ws . has ( window ) ; // false, window has been removedES6 führt eine neue Klassensyntax ein. Eine Sache, die hier zu beachten ist, ist, dass die ES6-Klasse kein neues objektorientiertes Vererbungsmodell ist. Sie dienen nur als syntaktischer Zucker über den vorhandenen prototypbasierten Vererbung von JavaScript.
Eine Möglichkeit, eine Klasse in ES6 zu betrachten, ist nur eine neue Syntax für die Arbeit mit Prototypen und Konstruktorfunktionen, die wir in ES5 verwenden würden.
Funktionen, die mit dem static Schlüsselwort definiert sind, implementieren statische/klasselige Funktionen in der Klasse.
class Task {
constructor ( ) {
console . log ( "task instantiated!" ) ;
}
showId ( ) {
console . log ( 23 ) ;
}
static loadAll ( ) {
console . log ( "Loading all tasks.." ) ;
}
}
console . log ( typeof Task ) ; // function
const task = new Task ( ) ; // "task instantiated!"
task . showId ( ) ; // 23
Task . loadAll ( ) ; // "Loading all tasks.."erstreckt sich und super im Unterricht
Betrachten Sie den folgenden Code:
class Car {
constructor ( ) {
console . log ( "Creating a new car" ) ;
}
}
class Porsche extends Car {
constructor ( ) {
super ( ) ;
console . log ( "Creating Porsche" ) ;
}
}
let c = new Porsche ( ) ;
// Creating a new car
// Creating Porsche extends ermöglicht die Kinderklasse, von der Elternklasse in ES6 zu erben. Es ist wichtig zu beachten, dass der abgeleitete Konstruktor super() aufrufen muss.
Außerdem können Sie die Methode der Elternklasse in den Methoden der untergeordneten Klasse unter Verwendung von super.parentMethodName()
Lesen Sie hier mehr über Klassen
Ein paar Dinge, die Sie beachten sollten:
function nicht verwendet werden. Ein Symbol ist ein eindeutiger und unveränderlicher Datentyp, der in ES6 eingeführt wird. Der Zweck eines Symbols ist es, eine eindeutige Kennung zu erzeugen, aber Sie können niemals Zugriff auf diese Kennung erhalten.
So erstellen Sie ein Symbol:
const sym = Symbol ( "some optional description" ) ;
console . log ( typeof sym ) ; // symbol Beachten Sie, dass Sie mit Symbol(…) nicht new verwenden können.
Wenn ein Symbol als Eigenschaft/Schlüssel eines Objekts verwendet wird, wird es auf eine besondere Weise gespeichert, dass die Eigenschaft nicht in einer normalen Aufzählung der Eigenschaften des Objekts angezeigt wird.
const o = {
val : 10 ,
[ Symbol ( "random" ) ] : "I'm a symbol" ,
} ;
console . log ( Object . getOwnPropertyNames ( o ) ) ; // val Um die Symboleigenschaften eines Objekts abzurufen, verwenden Sie Object.getOwnPropertySymbols(o)
Ein Iterator greift nacheinander auf die Elemente aus einer Sammlung zu, während er seine aktuelle Position in dieser Sequenz verfolgt. Es bietet eine next() -Methode, die das nächste Element in der Sequenz zurückgibt. Diese Methode gibt ein Objekt mit zwei Eigenschaften zurück: erledigt und Wert.
ES6 hat Symbol.iterator , der den Standard -Iterator für ein Objekt angibt. Immer wenn ein Objekt iteriert werden muss (z. B. zu Beginn von A for..of Loop), wird die @@ Iterator -Methode ohne Argumente aufgerufen, und der zurückgegebene Iterator wird verwendet, um die zu iterierten Werte zu erhalten.
Schauen wir uns ein Array an, das iterbar ist, und den Iterator, den es produzieren kann, um seine Werte zu konsumieren:
const arr = [ 11 , 12 , 13 ] ;
const itr = arr [ Symbol . iterator ] ( ) ;
itr . next ( ) ; // { value: 11, done: false }
itr . next ( ) ; // { value: 12, done: false }
itr . next ( ) ; // { value: 13, done: false }
itr . next ( ) ; // { value: undefined, done: true } Beachten Sie, dass Sie benutzerdefinierte Iteratoren schreiben können, indem Sie obj[Symbol.iterator]() mit der Objektdefinition definieren.
Generatorfunktionen sind eine neue Funktion in ES6, mit der eine Funktion im Laufe der Zeit viele Werte generieren kann, indem ein Objekt zurückgegeben wird, das Iterating für den Ziehen von Werten aus dem Funktionswert gleichzeitig wiederholt.
Eine Generatorfunktion gibt ein iterables Objekt zurück, wenn sie aufgerufen wird. Es wird mit der neuen * Syntax sowie dem in ES6 eingeführten neuen yield geschrieben.
function * infiniteNumbers ( ) {
let n = 1 ;
while ( true ) {
yield n ++ ;
}
}
const numbers = infiniteNumbers ( ) ; // returns an iterable object
numbers . next ( ) ; // { value: 1, done: false }
numbers . next ( ) ; // { value: 2, done: false }
numbers . next ( ) ; // { value: 3, done: false }Jedes Mal, wenn die Rendite aufgerufen wird, wird der nachgegebene Wert zum nächsten Wert in der Sequenz.
Beachten Sie außerdem, dass Generatoren ihre nachgegebenen Werte bei Bedarf berechnen, was es ihnen ermöglicht, Sequenzen effizient darzustellen, die teuer zu berechnen sind, oder sogar unendliche Sequenzen.
ES6 hat einheimische Unterstützung für Versprechen. Ein Versprechen ist ein Objekt, das auf eine asynchrone Operation wartet, und nach Abschluss dieser Operation wird das Versprechen entweder erfüllt (gelöst) oder abgelehnt.
Die Standardmethode, um ein Versprechen zu erstellen, besteht darin, den new Promise() -Konstruktor () zu verwenden, der einen Handler akzeptiert, der zwei Funktionen als Parameter erhält. Der erste Handler (in der Regel als resolve ) ist eine Funktion, die Sie mit dem zukünftigen Wert aufrufen können, wenn er fertig ist. und der Second -Handler (normalerweise als reject bezeichnet) ist eine Funktion zum Ablehnen des Versprechens, wenn er den zukünftigen Wert nicht beheben kann.
const p = new Promise ( ( resolve , reject ) => {
if ( /* condition */ ) {
resolve ( /* value */ ) ; // fulfilled successfully
} else {
reject ( /* reason */ ) ; // error, rejected
}
} ) ; Jedes Versprechen hat then eine Methode mit dem Namen, die ein Paar Rückrufe nimmt. Der erste Rückruf wird aufgerufen, wenn das Versprechen gelöst wird, während der zweite aufgerufen wird, wenn das Versprechen abgelehnt wird.
p . then ( ( val ) => console . log ( "Promise Resolved" , val ) ,
( err ) => console . log ( "Promise Rejected" , err ) ) ; Durch die Rückgabe eines Wertes von then Rückernständen wird der Wert an den nächsten then übergeben.
const hello = new Promise ( ( resolve , reject ) => { resolve ( "Hello" ) } ) ;
hello . then ( ( str ) => ` ${ str } World` )
. then ( ( str ) => ` ${ str } !` )
. then ( ( str ) => console . log ( str ) ) // Hello World!Bei der Rückkehr eines Versprechens wird der gelöste Wert des Versprechens an den nächsten Rückruf übergeben, um sie effektiv miteinander zu ketten. Dies ist eine einfache Technik, um "Callback -Hölle" zu vermeiden.
const p = new Promise ( ( resolve , reject ) => { resolve ( 1 ) } ) ;
const eventuallyAdd1 = ( val ) => new Promise ( ( resolve , reject ) => { resolve ( val + 1 ) } ) ;
p . then ( eventuallyAdd1 )
. then ( eventuallyAdd1 )
. then ( ( val ) => console . log ( val ) ) ; // 3