Share
Embed
Transcript
107 slides
-
Outline It's 2015 Already, Folks! New Features New Built-ins Less
Cool, But Still Worth Noting The "Beyond" Part Can I Have It All? Should We Use It? -
It's 2015 Already, Folks! After 6 years of hard work
of TC-39, ECMAScript® 2015 (a.k.a. ES6, ES.next or Harmony), the successor of ES5, got officially approved as a standard on June 17, 2015 by the ECMA General Assembly. ES2015 brings significant, awesome changes (although, mostly just syntactic sugars), so why not get to know it better? -
Arrow Functions Arrow functions (fat arrows) are syntactic sugar over
already known anonymous functions. / / E S 2 0 1 5 / / S h o r t v e r s i o n / / ( e x a c t l y O N E a r g u m e n t , i m m e d i a t e " r e t u r n " ) [ 1 , 2 , 3 ] . m a p ( e l = > e l * 2 ) ; / / S t a n d a r d v e r s i o n / / ( a n y a r g u m e n t s , s t a t e m e n t b l o c k w i t h o p t i o n a l " r e t u r n " ) [ 1 , 2 , 3 ] . m a p ( ( e l ) = > { r e t u r n e l * 2 ; } ) ; / / E S 5 E q u i v a l e n t [ 1 , 2 , 3 ] . m a p ( f u n c t i o n ( e l ) { r e t u r n e l * 2 ; } ) ; -
Arrow Functions (Lexical "this") "this" is automatically bound using the
current scope. / / E S 2 0 1 5 f u n c t i o n t i m e o u t ( ) { t h i s . h e l l o = " W o r l d ! " ; . . . s e t T i m e o u t ( ( ) = > { c o n s o l e . l o g ( t h i s . h e l l o ) ; } , 1 0 0 ) ; } n e w t i m e o u t ( ) ; / / E S 5 E q u i v a l e n t f u n c t i o n t i m e o u t ( ) { t h i s . h e l l o = " W o r l d ! " ; . . . v a r s e l f = t h i s ; s e t T i m e o u t ( f u n c t i o n ( ) { c o n s o l e . l o g ( s e l f . h e l l o ) ; } , 1 0 0 ) ; } n e w t i m e o u t ( ) ; -
Arrow Functions (Caveats) When using "return expression" syntax, remember to
wrap object literals in parenthesis... (Standalone object literal is treated as a block statement with jump statement defined and no return) / / B A D , s t a t e m e n t b l o c k , " m y p r o p " i s a l a b e l ( ) = > { m y p r o p : t r u e } = > u n d e f i n e d / / G O O D , o b j e c t l i t e r a l ( ) = > ( { m y p r o p : t r u e } ) = > { m y p r o p : t r u e } -
Let (... is the new "var") "let" allows us to
use "block-scoped" variables, instead of "hoisted" ones (yes, I'm looking at you, "var"...) / / E S 2 0 1 5 f u n c t i o n t e s t ( ) { { l e t b = 2 ; } c o n s o l e . l o g ( b ) ; / / R e f e r e n c e E r r o r : b i s n o t d e f i n e d / / " b " w a s n o t h o i s t e d / / t o t h e t o p o f " t e s t " } / / E S 5 E q u i v a l e n t f u n c t i o n t e s t ( ) { ( f u n c t i o n ( ) { v a r b = 2 ; } ) ( ) ; c o n s o l e . l o g ( b ) ; / / R e f e r e n c e E r r o r : b i s n o t d e f i n e d / / " b " w a s h o i s t e d / / o n l y t o t h e t o p o f I I F E } -
Let (... to the rescue - callbacks) "let" is useful
when dealing with callbacks (and "for" loops) / / E S 2 0 1 5 f o r ( l e t i = 0 ; i < 5 ; + + i ) { s e t T i m e o u t ( f u n c t i o n ( ) { c o n s o l e . l o g ( i ) ; } , 1 0 0 ) ; } / / P r i n t s 0 , 1 , 2 , 3 , 4 / / E S 5 E q u i v a l e n t f o r ( v a r i = 0 ; i < 5 ; + + i ) { ( f u n c t i o n ( j ) { s e t T i m e o u t ( f u n c t i o n ( ) { c o n s o l e . l o g ( j ) ; } , 1 0 0 ) ; } ) ( i ) ; } / / E S 5 ' s c o m m o n b u g ( w i t h o u t I I F E ) f o r ( v a r i = 0 ; i < 5 ; + + i ) { s e t T i m e o u t ( f u n c t i o n ( ) { c o n s o l e . l o g ( i ) ; } , 1 0 0 ) ; } / / P r i n t s " 5 " f i v e t i m e s -
Const It's just like "let" (block-scoped)... but constant! / /
E S 2 0 1 5 c o n s t x = 1 ; x = 2 ; / / S y n t a x E r r o r : i n v a l i d a s s i g n m e n t t o c o n s t x / / E S 5 S e m i E q u i v a l e n t ( " x " h a s t o b e a p r o p e r t y o f a n o b j e c t ) O b j e c t . d e f i n e P r o p e r t y ( w i n d o w , " x " , { v a l u e : 1 , w r i t a b l e : f a l s e } ) ; x = 2 ; / / S i l e n t l y f a i l s , " x " w o n ' t b e m o d i f i e d c o n s o l e . l o g ( x ) ; = > 1 -
Classes Syntactic sugar over the well-known prototype-based classes / /
E S 2 0 1 5 c l a s s C a r { c o n s t r u c t o r ( m a x S p e e d ) { t h i s . m a x S p e e d = m a x S p e e d ; t h i s . c u r S p e e d = 0 ; } s p e e d ( ) { t h i s . c u r S p e e d + = 5 ; } } / / A n o n y m o u s c l a s s v a r a n o n = n e w ( c l a s s { . . . } ) ( ) ; / / E S 5 E q u i v a l e n t v a r C a r = f u n c t i o n ( m a x S p e e d ) { t h i s . m a x S p e e d = m a x S p e e d ; t h i s . c u r S p e e d = 0 ; } ; C a r . p r o t o t y p e . s p e e d = f u n c t i o n ( ) { t h i s . c u r S p e e d + = 5 ; } ; / / A n o n y m o u s C l a s s E q u i v a l e n t / / ( w r a p p e d i n I I F E f o r s c o p i n g ) v a r a n o n = ( f u n c t i o n ( ) { / / . . . p r o t o t y p e p r e p a r a t i o n r e t u r n n e w p r e p a r e d C l a s s ( ) ; } ) ( ) ; -
Classes (Inheritance, part 1) Hello "extend", my old friend! /
/ E S 2 0 1 5 c l a s s S p o r t s C a r e x t e n d s C a r { t u r b o ( ) { t h i s . c u r S p e e d + = 2 5 ; } } / / E S 5 E q u i v a l e n t v a r S p o r t s C a r = f u n c t i o n ( ) { C a r . a p p l y ( t h i s , a r g u m e n t s ) ; } ; v a r p r o t o = S p o r t s C a r . p r o t o t y p e ; p r o t o = O b j e c t . c r e a t e ( C a r . p r o t o t y p e ) ; p r o t o . c o n s t r u c t o r = S p o r t s C a r ; p r o t o . t u r b o = f u n c t i o n ( ) { t h i s . c u r S p e e d + = 2 5 ; } -
Classes (Inheritance, part 2) Base class can also be an
expression result / / E S 2 0 1 5 f u n c t i o n m i x i n ( B a s e C l a s s , n a m e , f u n ) { l e t b a s e = c l a s s C o m b i n e d e x t e n d s B a s e C l a s s { } ; b a s e . p r o t o t y p e [ n a m e ] = f u n ; r e t u r n b a s e ; } l e t b r a k e s = f u n c t i o n ( ) { t h i s . c u r S p e e d = 0 ; } ; c l a s s S p o r t s C a r e x t e n d s m i x i n ( C a r , " b r a k e s " , b r a k e s ) { t u r b o ( ) { t h i s . c u r S p e e d + = 2 5 ; } } -
Classes (super) Super™ easy access to base class constructor &
methods / / E S 2 0 1 5 c l a s s S p o r t s C a r e x t e n d s C a r { c o n s t r u c t o r ( ) { s u p e r ( ) ; } s p e e d ( ) { s u p e r . s p e e d ( ) ; t h i s . c u r S p e e d + = 1 0 ; / / T o t a l a c c e l e r a t i o n 1 5 ! } } / / E S 5 E q u i v a l e n t v a r S p o r t s C a r = f u n c t i o n ( ) { C a r . a p p l y ( t h i s , a r g u m e n t s ) ; } ; S p o r t s C a r . p r o t o t y p e = O b j e c t . c r e a t e ( C a r . p r o t o t y p e ) ; v a r p r o t o = S p o r t s C a r . p r o t o t y p e ; p r o t o . c o n s t r u c t o r = S p o r t s C a r ; p r o t o . s p e e d = f u n c t i o n ( ) { C a r . p r o t o t y p e . s p e e d . c a l l ( t h i s ) ; t h i s . c u r S p e e d + = 1 0 ; / / T o t a l a c c e l e r a t i o n 1 5 ! } -
Classes (Static Methods) No instance? No problem! / / E
S 2 0 1 5 c l a s s C a r { s t a t i c g e t M a n u f a c t u r e r ( ) { r e t u r n " M e g a C o r p " ; } } / / E S 5 E q u i v a l e n t v a r C a r = f u n c t i o n ( ) { . . . } ; C a r . g e t M a n u f a c t u r e r = f u n c t i o n ( ) { r e t u r n " M e g a C o r p " ; } -
Classes (Getters & Setters) Tired of "getCats()"? Well, say no
more... / / E S 2 0 1 5 c l a s s C a r { g e t f u e l C o n s u m p t i o n ( ) { r e t u r n ( t h i s . c u r S p e e d * 5 ) ; } s e t l i g h t s ( o n ) { t h i s . _ l i g h t s = ! ! o n ; } } / / E S 5 E q u i v a l e n t v a r C a r = f u n c t i o n ( ) { . . . } ; C a r . p r o t o t y p e = { g e t f u e l C o n s u m p t i o n ( ) { r e t u r n ( t h i s . c u r S p e e d * 5 ) ; } , s e t l i g h t s ( o n ) { t h i s . _ l i g h t s = ! ! o n ; } } ; C a r . p r o t o t y p e . c o n s t r u c t o r = C a r ; -
Classes (JS2015 Sadness ) Unfortunatelly, no properties initializers for
now (pending proposal for ES2016 / ES7) / / W o r k s i n E S 2 0 1 6 / / ( b u t n o t i n E S 2 0 1 5 ) c l a s s C a r { y e a r = 2 0 1 5 ; s t a t i c m a n u f a c t u r e r = " M e g a C o r p " ; } / / W o r k a r o u n d ( E S 2 0 1 5 ) c l a s s C a r { c o n s t r u c t o r ( ) { t h i s . y e a r = 2 0 1 5 ; } } C a r . m a n u f a c t u r e r = " M e g a C o r p " ; -
Modules In-code modules exporting/importing, without global namespace garbage / /
E x p o r t e x a m p l e s ( " l i b . j s " ) e x p o r t c l a s s t e s t { . . . } ; e x p o r t f u n c t i o n g r e e t = f u n c t i o n ( ) { } ; e x p o r t v a r m a g i c N u m b e r = 4 2 ; e x p o r t c o n s t p i = 3 . 1 4 ; e x p o r t d e f a u l t c l a s s M y C l a s s { . . . } ; e x p o r t * f r o m " n e s t e d L i b " ; / / I m p o r t e x a m p l e s ( " a p p . j s " ) i m p o r t { g r e e t , p i } f r o m " l i b " ; i m p o r t M y C l a s s f r o m " l i b " ; i m p o r t * a s l i b f r o m " l i b " ; i m p o r t m y D e f a u l t , { g r e e t a s f u n , p i } f r o m " l i b " -
Modules Pros No global namespace polution Import what you need
Statical (compile-time) structure analysis Async-load ready Cyclic dependencies support (export bindings, not values) Implicit "use strict"! Cons No conditional exports -
Modules ("import all" example) "This library is awesome, I want
all of it..." / / E S 2 0 1 5 / / " l i b . j s " e x p o r t f u n c t i o n g r e e t = f u n c t i o n ( ) { r e t u r n " H e l l o , w o r l d ! " ; } ; e x p o r t v a r m a g i c = 4 2 ; / / " a p p . j s " i m p o r t * a s m y L i b f r o m " l i b " ; c o n s o l e . l o g ( m y L i b . g r e e t ( ) ) ; c o n s o l e . l o g ( m y L i b . m a g i c ) ; / / E S 5 E q u i v a l e n t ( G l o b a l s p o l u t i o n ) / / " l i b . j s " L i b = { } ; L i b . g r e e t = f u n c t i o n ( ) { r e t u r n " H e l l o , w o r l d ! " ; } ; L i b . m a g i c = 4 2 ; / / " a p p . j s " v a r m y L i b = L i b ; c o n s o l e . l o g ( m y L i b . g r e e t ( ) ) ; c o n s o l e . l o g ( m y L i b . m a g i c ) ; -
Modules ("destructured import" example) "...and this has some nice parts
too, give them to me!" / / E S 2 0 1 5 / / " l i b . j s " e x p o r t f u n c t i o n f u n = f u n c t i o n ( ) { } ; e x p o r t v a r m a g i c = 4 2 ; / / " a p p . j s " i m p o r t { f u n , m a g i c } f r o m " l i b " ; c o n s o l e . l o g ( f u n ( ) ) ; c o n s o l e . l o g ( m a g i c ) ; / / = > 4 2 / / E S 5 E q u i v a l e n t ( G l o b a l s p o l u t i o n ) / / " l i b . j s " L i b = { } ; L i b . f u n = f u n c t i o n ( ) { } ; L i b . m a g i c = 4 2 ; / / " a p p . j s " v a r m y L i b = L i b ; c o n s o l e . l o g ( m y L i b . g r e e t ( ) ) ; c o n s o l e . l o g ( m y L i b . m a g i c N u m b e r ) ; -
Modules ("defaults & aliases" example) "I always want the cake,
and then some..." / / E S 2 0 1 5 / / " l i b . j s " e x p o r t f u n c t i o n f u n = f u n c t i o n ( ) { } ; e x p o r t v a r m a g i c = 4 2 ; e x p o r t d e f a u l t 1 ; / / " a p p . j s " i m p o r t d e f , { f u n a s f } f r o m " l i b " ; c o n s o l e . l o g ( f ( ) ) ; c o n s o l e . l o g ( d e f ) ; / / = > 1 / / " v a r m a g i c " n o t i m p o r t e d / / E S 5 E q u i v a l e n t ( G l o b a l s p o l u t i o n ) / / " l i b . j s " L i b = { } ; L i b . f u n = f u n c t i o n ( ) { } ; L i b . m a g i c = 4 2 ; L i b . d e f = 1 ; / / " a p p . j s " v a r d e f = L i b . d e f , f = L i b . f u n ; c o n s o l e . l o g ( f ( ) ) ; c o n s o l e . l o g ( d e f ) ; / / = > 1 / / " L i b . m a g i c " a v a i l a b l e / / ( b e c a u s e o f g l o b a l p o l u t i o n ) -
Modules ("Reexporting with wildcard" example) "Hey, I'll borrow your stuff...
And now it's mine" / / E S 2 0 1 5 / / " n e s t e d L i b . j s " e x p o r t f u n c t i o n f u n = f u n c t i o n ( ) { } ; e x p o r t d e f a u l t 1 ; / / " l i b . j s " e x p o r t * f r o m " n e s t e d L i b " ; / / " a p p . j s " i m p o r t d e f , { f u n a s f } f r o m " l i b " ; c o n s o l e . l o g ( f ( ) ) ; c o n s o l e . l o g ( d e f ) ; / / = > 1 / / E S 5 E q u i v a l e n t ( G l o b a l s p o l u t i o n ) / / " l i b A . j s " L i b A = { } ; L i b A . f u n = f u n c t i o n ( ) { } ; L i b A . d e f = 1 ; / / " l i b . j s " L i b = { } ; f o r ( e l i n L i b A ) i f ( L i b A . h a s O w n P r o p e r t y ( e l ) ) L i b [ e l ] = L i b A [ e l ] ; / / " a p p . j s " v a r d e f = L i b . d e f , f = L i b . f u n ; c o n s o l e . l o g ( f ( ) ) ; c o n s o l e . l o g ( d e f ) ; / / = > 1 -
Enhanced Properties (Property & method shorthand) Easier object literal creation
using existing variables v a r x = 2 ; v a r y = 4 ; v a r f = f u n c t i o n ( x ) { r e t u r n x ; } ; v a r o b j = { x , y , f } ; / / = > o b j = { x : 2 , y : 4 , f : f u n c t i o n ( x ) { r e t u r n x ; } } -
Enhanced Properties (Method short notation) Much simpler methods notation for
objects v a r o b j = { p o s ( x , y ) { r e t u r n " Y o u p o s : " + x + " , " + y ; } } ; o b j . p o s ( 1 , 2 ) ; / / = > Y o u p o s : 1 , 2 -
Enhanced Properties ("super" methods) Whoops, you have covered this method,
right? No biggie... v a r o b j = { t o S t r i n g ( ) { r e t u r n " [ L o g ] " + s u p e r . t o S t r i n g ( ) ; } } ; o b j . t o S t r i n g ( ) ; / / = > " [ L o g ] [ o b j e c t O b j e c t ] " -
Enhanced Properties (Computed properties) Dynamically computed property names for the
asking v a r x = " m y P r o p " ; v a r f o o = f u n c t i o n ( ) { r e t u r n " b a r " ; } ; v a r o b j = { / / P r o p e r t i e s [ " f o o " + f o o ( ) ] : 4 2 , / / M e t h o d s [ " f o o " + " m e t h o d " ] ( x ) { r e t u r n x ; } , / / G e t t e r s & S e t t e r s g e t [ x ] ( ) { r e t u r n 1 2 3 ; } , s e t [ x ] ( a ) { t h i s . _ m y P r o p = a ; } } ; / / o b j . f o o b a r = > 4 2 / / o b j . f o o m e t h o d ( 1 ) = > 1 / / o b j . m y P r o p = > 1 2 3 / / o b j . m y P r o p = 2 3 4 ; = > o b j . _ m y P r o p = 2 3 4 ; -
Destructuring (Basics) Syntactic sugar over object/arrays props matching / /
A r r a y s v a r h e r o e s L i s t = [ " W a y n e " , " K e n t " , " A l l e n " , " Q u e e n " ] ; v a r [ b a t m a n , s u p e r m a n ] = h e r o e s L i s t ; / / b a t m a n = > " W a y n e " / / s u p e r m a n = > " K e n t " / / A r r a y s i g n o r i n g e l e m e n t s v a r [ b a t m a n , , , a r r o w ] = h e r o e s L i s t ; / / a r r o w = > " Q u e e n " / / O b j e c t s v a r h e r o e s = { b a t m a n : " W a y n e " , s u p e r m a n : " K e n t " } ; v a r { b a t m a n , s u p e r m a n } = h e r o e s ; / / b a t m a n = > " W a y n e " / / s u p e r m a n = > " K e n t " -
Destructuring (Aliases) "I don't want to call it like this
anymore..." / / A l i a s i n g ( O b j e c t s o n l y ) v a r h e r o e s = { b a t m a n : " W a y n e " , s u p e r m a n : " K e n t " } ; v a r { b a t m a n , s u p e r m a n : k a l E l } = h e r o e s ; / / b a t m a n = > " W a y n e " / / k a l E l = > " K e n t " -
Destructuring (Deep Matching) We need to go deeper... / /
D e e p M a t c h i n g ( N e s t e d O b j e c t s e x a m p l e ) v a r h e r o e s = { d c : { b a t m a n : " W a y n e " , s u p e r m a n : " K e n t " } , m a r v e l : { i r o n m a n : " S t a r k " } } ; v a r { d c : { b a t m a n } , m a r v e l : { i r o n m a n } } = h e r o e s ; / / b a t m a n = > " W a y n e " / / i r o n m a n = > " S t a r k " / / D e e p M a t c h i n g ( M i x e d A r r a y & O b j e c t m a t c h i n g ) v a r h e r o e s L i s t = [ { d c : [ " W a y n e " , " K e n t " ] } , { m a r v e l : [ " S t a r k " ] } ] ; v a r [ { d c : [ b a t m a n ] } , { m a r v e l : [ i r o n m a n ] } ] = h e r o e s L i s t ; / / b a t m a n = > " W a y n e " / / i r o n m a n = > " S t a r k " -
Destructuring (Also, within functions' arguments) / / A r g
u m e n t s a s a n a r r a y f u n c t i o n h e r o ( [ f i r s t N a m e , l a s t N a m e ] ) { c o n s o l e . l o g ( f i r s t N a m e + " " + l a s t N a m e ) ; } / / h e r o ( " B r u c e " , " W a y n e " ) = > " B r u c e W a y n e " / / O b j e c t s s h o r t h a n d m a t c h i n g ( a l i a s e s s u p p o r t e d ) f u n c t i o n h e r o ( { f i r s t N a m e : n a m e , l a s t N a m e : s u r n a m e } ) { c o n s o l e . l o g ( n a m e + " " + s u r n a m e ) ; } / / h e r o ( { f i r s t N a m e : " C l a r k " , l a s t N a m e : " K e n t " } ) = > " C l a r k K e n t " -
Destructuring (Fail-soft with defaults) Missing matches won't throw errors v
a r o b j = { i r o n m a n : " S t a r k " , c a p t a i n : " R o g e r s " } ; v a r l i s t = [ " W a y n e " , " K e n t " ] ; / / D e f a u l t b e h a v i o u r f i l l w i t h " u n d e f i n e d " v a r { i r o n m a n , c a p t a i n , h u l k } = o b j ; v a r [ b a t m a n , s u p e r m a n , w o n d e r w o m a n ] = l i s t ; / / h u l k = > u n d e f i n e d / / w o n d e r w o m a n = > u n d e f i n e d / / W i t h u s e r d e f i n e d d e f a u l t s v a r { i r o n m a n , c a p t a i n , b l a c k w i d o w = " R o m a n o v a " } = o b j ; v a r [ b a t m a n , s u p e r m a n , f l a s h = " A l l e n " ] = l i s t ; / / b l a c k w i d o w = > R o m a n o v a / / f l a s h = > A l l e n -
Destructuring (Deep Matching Caveat) Deep Matching won't work with undefined
objects on path... / / T h i s w o n ' t w o r k v a r h e r o e s = { d c : { b a t m a n : " W a y n e " , s u p e r m a n : " K e n t " } } ; v a r { m a r v e l : { i r o n m a n } } = h e r o e s ; / / T y p e E r r o r : c a n ' t c o n v e r t u n d e f i n e d t o o b j e c t ...however, "default" parameter solves the problem v a r { m a r v e l : { i r o n m a n } = { i r o n m a n : " R h o d e s ? " } } = h e r o e s ; / / b a t m a n = > " W a y n e " / / i r o n m a n = > " R h o d e s ? " -
Default Parameters Default value for empty function arguments / /
E S 2 0 1 5 f u n c t i o n i d ( n a m e , s u r n a m e = " D o e " ) { r e t u r n n a m e + " " + s u r n a m e ; } / / i d ( " W a l t e r " , " W h i t e " ) / / = > W a l t e r W h i t e / / i d ( " J a n e " ) / / = > " J a n e D o e " / / E S 5 E q u i v a l e n t f u n c t i o n i d ( n a m e , s u r n a m e ) { i f ( s u r n a m e = = = u n d e f i n e d ) { s u r n a m e = " D o e " ; } r e t u r n n a m e + " " + s u r n a m e ; } / / i d ( " W a l t e r " , " W h i t e " ) / / = > W a l t e r W h i t e / / i d ( " J a n e " ) / / = > " J a n e D o e " -
Default Parameters (Nifty trick - using previous params) / /
E S 2 0 1 5 f u n c t i o n g r e e t ( g r e e t i n g , n a m e = g r e e t i n g ) { r e t u r n g r e e t i n g + " " + n a m e ; } / / g r e e t ( " H e l l o " , " W a l t e r " ) / / = > H e l l o W a l t e r / / g r e e t ( " H e l l o " ) / / = > " H e l l o H e l l o " -
"Rest" Parameter No more slicing up argument! / / E
S 2 0 1 5 f u n c t i o n e x t r a c t T a i l ( f i r s t , . . . o t h e r s ) { r e t u r n o t h e r s ; } e x t r a c t T a i l ( 1 , 2 , 3 , 4 , 5 ) ; / / = > [ 2 , 3 , 4 , 5 ] / / E S 5 E q u i v a l e n t v a r s l i c e = A r r a y . p r o t o t y p e . s l i c e ; f u n c t i o n e x t r a c t T a i l ( ) { r e t u r n s l i c e . c a l l ( a r g u m e n t s , 1 ) ; } e x t r a c t T a i l ( 1 , 2 , 3 , 4 , 5 ) ; / / = > [ 2 , 3 , 4 , 5 ] -
"Spread" Operator Spread that elements all over your arrays... /
/ E S 2 0 1 5 f u n c t i o n m y S e q u e n c e ( o t h e r s ) { r e t u r n [ 1 , 2 , 3 , . . . o t h e r s ] ; } m y S e q u e n c e ( [ 4 , 5 , 6 ] ) ; / / = > [ 1 , 2 , 3 , 4 , 5 , 6 ] / / E S 5 E q u i v a l e n t f u n c t i o n m y S e q u e n c e ( o t h e r s ) { r e t u r n [ 1 , 2 , 3 ] . c o n c a t ( o t h e r s ) } m y S e q u e n c e ( [ 4 , 5 , 6 ] ) ; / / = > [ 1 , 2 , 3 , 4 , 5 , 6 ] -
"Spread" Operator (super()'s best companion) Just spread your "arguments", no
more "apply()"! c l a s s C a r { c o n s t r u c t o r ( o w n e r ) { t h i s . o w n e r = o w n e r ; } } c l a s s S p o r t s C a r e x t e n d s C a r { c o n s t r u c t o r ( . . . a r g s ) { s u p e r ( . . . a r g s ) ; } } ( n e w S p o r t s C a r ( " m e " ) ) . o w n e r ; / / = > m e -
"Spread" Operator (Fun with Arrays) v a r l i
s t = [ " S t a r k " , " R o g e r s " , " B a n n e r " ] ; v a r [ i r o n m a n , . . . o t h e r s ] = l i s t ; o t h e r s ; / / = > [ " R o g e r s " , " B a n n e r " ] ; -
Template Strings No more strings appending / / E S
2 0 1 5 / / B a s i c e x a m p l e ` E x a m p l e s t r i n g ` / / M u l t i l i n e ` L i n e 1 L i n e 2 ` / / I n t e r p o l a t i o n v a r n u m b e r = 4 2 ; ` A n s w e r t o e v e r y t h i n g : $ { n u m b e r } ` / / = > " T h e A n s w e r t o e v e r y t h i n g : 4 2 " / / E x p r e s s i o n i n s i d e i n t e r p o l a t i o n v a r p r i c e = 2 . 5 ; ` T h r e e a p p l e s c o s t : $ { p r i c e * 3 } ` / / = > " T h r e e a p p l e s c o s t : 7 . 5 " / / E S 5 E q u i v a l e n t / / B a s i c e x a m p l e " E x a m p l e s t r i n g " / / M u l t i l i n e " L i n e 1 \ n " + " L i n e 2 " / / I n t e r p o l a t i o n v a r n u m b e r = 4 2 ; " A n s w e r t o e v e r y t h i n g : " + n u m b e r / / = > " T h e A n s w e r t o e v e r y t h i n g : 4 2 " / / E x p r e s s i o n i n s i d e i n t e r p o l a t i o n v a r p r i c e = 2 . 5 ; " T h r e e a p p l e s c o s t : " + ( p r i c e * 3 ) / / = > " T h r e e a p p l e s c o s t : 7 . 5 " -
Iterator Protocol Any object can be an iterator - the
only requirement is to implement a "next()" method, returning object with props: "done" (has iteration finished?) "value" (current iteration value) f u n c t i o n i t e r a t o r ( n ) { v a r n e x t V a l u e = 0 ; r e t u r n { n e x t : f u n c t i o n ( ) { r e t u r n { d o n e : ! ( n e x t V a l u e < n ) , v a l u e : n e x t V a l u e + + } ; } } ; } v a r i t = i t e r a t o r ( 2 ) ; i t . n e x t ( ) / / = > { d o n e : f a l s e , v a l u e : 0 } i t . n e x t ( ) / / = > { d o n e : f a l s e , v a l u e : 1 } i t . n e x t ( ) / / = > { d o n e : t r u e , v a l u e : . . . } -
Iterable Protocol (for..of) Any object with @@iterator (don't worry about
that, yet...) defined can be iterated over using "for..of" loop Built-in iterable objects: String, Array, TypedArray, Map & Set / / E S 2 0 1 5 v a r l i s t = [ " a " , " b " , " c " ] ; f o r ( v a r x o f l i s t ) { c o n s o l e . l o g ( x ) ; } / / = > " a " , " b " , " c " / / E S 5 E q u i v a l e n t v a r l i s t = [ " a " , " b " , " c " ] ; f o r ( v a r x i n l i s t ) { i f ( l i s t . h a s O w n P r o p e r t y ( x ) ) c o n s o l e . l o g ( l i s t [ x ] ) ; } / / = > " a " , " b " , " c " -
Iterable Protocol (@@iterator) @@iterator is a method identified by the
built-in Symbol ([Symbol.iterator] - Computed property). It should conform to the Iterator Protocol v a r o b j = { } o b j [ S y m b o l . i t e r a t o r ] = f u n c t i o n ( ) { l e t v a l u e = 0 , m a x = 3 ; r e t u r n { n e x t : f u n c t i o n ( ) { r e t u r n { d o n e : ! ( v a l u e < m a x ) , v a l u e : v a l u e + + } ; } } ; } ; / / " f o r . . o f " l o o p i t e r a t i o n f o r ( v a r x o f o b j ) { c o n s o l e . l o g ( x ) ; } / / = > 0 , 1 , 2 / / " S p r e a d " o p e r a t o r i t e r a t i o n [ . . . o b j ] / / = > [ 0 , 1 , 2 ] / / D e s t r u c t u r i n g i t e r a t i o n v a r [ a , b , c ] = o b j a / / = > 0 b / / = > 1 c / / = > 2 -
Iterable Protocol (To Infinity... and beyond!) v a r o
b j = { } o b j [ S y m b o l . i t e r a t o r ] = f u n c t i o n ( ) { l e t v a l u e = 0 ; r e t u r n { n e x t : f u n c t i o n ( ) { r e t u r n { d o n e : f a l s e , v a l u e : v a l u e + + } ; } } ; } ; / / I n f i n i t e i t e r a t i o n / / d o n o t t r y t h i s a t h o m e ! f o r ( v a r x o f o b j ) { c o n s o l e . l o g ( x ) ; } / / = > 0 , 1 , 2 , 3 , 4 , 5 . . . I n f i n i t y -
Generators Generators produce @@iterator-like methods. Use "yield" keyword to return
a value (by pausing execution of the method body) v a r o b j = { } v a r i t e r = f u n c t i o n * ( ) { l e t v a l u e = 0 , m a x = 3 ; w h i l e ( v a l u e < m a x ) { y i e l d v a l u e + + ; } } ; o b j [ S y m b o l . i t e r a t o r ] = i t e r ; f o r ( v a r x o f o b j ) { c o n s o l e . l o g ( x ) ; } / / = > 0 , 1 , 2 -
Generators (Both Iterable & Iterator compliant) Generators can be directly
used as Iterables, as they conform both Iterable & Iterator Protocols. v a r i t e r = f u n c t i o n * ( ) { l e t v a l u e = 0 , m a x = 3 ; w h i l e ( v a l u e < m a x ) { y i e l d v a l u e + + ; } } ; f o r ( v a r x o f i t e r ( ) ) { c o n s o l e . l o g ( x ) ; } / / = > 0 , 1 , 2 -
Generators (Nested Generators) When using generators inside generators, use "yield*"
to yield on all nested generator values v a r i t e r = f u n c t i o n * ( ) { l e t v a l u e = 1 , m a x = 4 ; w h i l e ( v a l u e < m a x ) { y i e l d v a l u e + + ; } } ; v a r o u t I t e r = f u n c t i o n * ( ) { y i e l d 0 ; y i e l d * i t e r ( ) ; y i e l d 4 ; } f o r ( v a r x o f o u t I t e r ( ) ) { c o n s o l e . l o g ( x ) ; } / / = > 0 , 1 , 2 , 3 , 4 -
Generators (Spread Generators) Generators can also be used as spread
operator arguments v a r i t e r = f u n c t i o n * ( ) { l e t v a l u e = 0 , m a x = 3 ; w h i l e ( v a l u e < m a x ) { y i e l d v a l u e + + ; } } ; [ . . . i t e r ( ) ] / / = > [ 0 , 1 , 2 ] -
Promises Built-in promises implementation, with Promises/A+ compliancy & more sugar
/ / R e s o l v i n g v a r r e s o l v e d = n e w P r o m i s e ( f u n c t i o n ( r e s o l v e , r e j e c t ) { s e t T i m e o u t ( f u n c t i o n ( ) { r e s o l v e ( 4 2 ) ; } , 1 0 0 0 ) ; } ) ; / / R e j e c t i n g v a r r e j e c t e d = n e w P r o m i s e ( f u n c t i o n ( r e s o l v e , r e j e c t ) { s e t T i m e o u t ( f u n c t i o n ( ) { r e j e c t ( 4 2 ) ; } , 1 0 0 0 ) ; } ) ; v a r o n D o n e = f u n c t i o n ( v a l ) { c o n s o l e . l o g ( " R e s o l v e d w i t h : " + v a l ) ; } ; v a r o n F a i l = f u n c t i o n ( v a l ) { c o n s o l e . l o g ( " R e j e c t e d w i t h : " + v a l ) ; } ; r e s o l v e d . t h e n ( o n D o n e , o n F a i l ) ; / / = > [ A f t e r t i m e o u t p a s s e s ] " R e s o l v e d w i t h : 4 2 " r e j e c t e d . t h e n ( o n D o n e , o n F a i l ) ; / / = > [ A f t e r t i m e o u t p a s s e s ] " R e j e c t e d w i t h : 4 2 " -
Promises (API) / / C r e a t e
a n e w P r o m i s e / / * r e s o l v e f u n c t i o n , c a l l e d r e s o l v e s t h e p r o m i s e w i t h v a l u e / / * r e j e c t f u n c t i o n , c a l l e d r e j e c t s t h e p r o m i s e w i t h v a l u e / / r e t u r n s a n e w p r o m i s e v a r p r o m i s e = n e w P r o m i s e ( f u n c t i o n ( r e s o l v e , r e j e c t ) { . . . } ) ; / / A t t a c h r e s o l u t i o n & r e j e c t i o n c a l l b a c k s / / * o n F u l f i l l e d f u n c t i o n , c a l l e d o n p r o m i s e r e s o l u t i o n / / * o n R e j e c t e d f u n c t i o n , c a l l e d o n p r o m i s e r e j e c t i o n ( o p t i o n a l ) / / r e t u r n s a n e w p r o m i s e ( f o r c h a i n i n g ) p r o m i s e . t h e n ( o n F u l f i l l e d , o n R e j e c t e d ) ; / / A t t a c h r e j e c t i o n c a l l b a c k / / * o n R e j e c t e d f u n c t i o n , c a l l e d o n p r o m i s e r e j e c t i o n / / r e t u r n s a n e w p r o m i s e ( f o r c h a i n i n g ) p r o m i s e . c a t c h ( o n R e j e c t e d ) ; -
Promises (Helpers) / / W a i t f o
r A L L p r o m i s e s t o r e s o l v e / / ( r e j e c t s o n a n y p r o m i s e r e j e c t i o n ) / / * p r o m i s e s a r r a y , e l e m e n t s a r e p r o m i s e s / / r e t u r n s a n e w p r o m i s e P r o m i s e . a l l ( p r o m i s e s ) ; / / W a i t f o r A N Y p r o m i s e t o r e s o l v e / / ( r e j e c t s w h e n r e j e c t i o n c a m e b e f o r e a n y r e s o l u t i o n ) / / * p r o m i s e s a r r a y , e l e m e n t s a r e p r o m i s e s / / r e t u r n s a n e w p r o m i s e P r o m i s e . r a c e ( p r o m i s e s ) ; -
Promises (Factories) / / C r e a t e
s a r e s o l v e d p r o m i s e w i t h p a s s e d v a l u e / / * v a l u e a n y , p r o m i s e r e s o l u t i o n v a l u e / / r e t u r n s a n e w , r e s o l v e d p r o m i s e P r o m i s e . r e s o l v e ( v a l u e ) ; / / C r e a t e s a r e j e c t e d p r o m i s e w i t h p a s s e d r e a s o n / / * r e a s o n a n y , p r o m i s e r e j e c t i o n r e a s o n / / r e t u r n s a n e w , r e j e c t e d p r o m i s e P r o m i s e . r e j e c t ( r e a s o n ) ; -
Promises (Chaining) Both then() and catch() return new promises, either
resolved (when callback returned a value) or rejected (when callback has thrown an error) v a r r e s o l v e d = P r o m i s e . r e s o l v e ( 4 2 ) ; v a r r e j e c t e d = P r o m i s e . r e j e c t ( 4 2 ) ; r e s o l v e d . t h e n ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e s o l v e d : " + x ) ; t h r o w x ; } ) . c a t c h ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e j e c t e d : " + x ) ; r e t u r n x ; } ) . t h e n ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e s o l v e d : " + x ) ; } ) ; / / = > " R e s o l v e d : 4 2 " , " R e j e c t e d : 4 2 " , " R e s o l v e d : 4 2 " r e j e c t e d . c a t c h ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e j e c t e d : " + x ) ; r e t u r n x ; } ) . t h e n ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e s o l v e d : " + x ) ; t h r o w x ; } ) . c a t c h ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e j e c t e d : " + x ) ; } ) ; / / = > " R e j e c t e d : 4 2 " , " R e s o l v e d : 4 2 " , " R e j e c t e d : 4 2 " -
Promises (Returning promises) Returning a promise in one of the
callbacks inserts that promise into the chain v a r r e s o l v e d = P r o m i s e . r e s o l v e ( 4 2 ) ; r e s o l v e d . t h e n ( f u n c t i o n ( x ) { r e t u r n P r o m i s e . r e s o l v e ( 2 4 ) ; } ) . t h e n ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e s o l v e d : " + x ) ; r e t u r n P r o m i s e . r e j e c t ( 4 2 ) ; } ) . c a t c h ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e j e c t e d : " + x ) ; } ) ; / / = > " R e s o l v e d : 2 4 " , " R e j e c t e d : 4 2 " -
Promises (Duck-typed promises matching) Returned values are matched by duck-typing,
so returning an object with ".then()" method treats it as a Promise. We can leverage this feature to transform jQuery's Promises into native ones. v a r a j a x = $ . a j a x ( . . . ) ; / / j Q u e r y ' s p r o m i s e h a s " . t h e n ( ) " m e t h o d , / / s o i t ' s " t h e n a b l e " , t h e r e f o r e i t ' s c o n s i d e r e d a P r o m i s e v a r w r a p p e r = P r o m i s e . r e s o l v e ( a j a x ) ; / / N a t i v e P r o m i s e " . t h e n ( ) " m e t h o d i n v o k e d w r a p p e r . t h e n ( f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e s o l v e d " ) ; } , f u n c t i o n ( x ) { c o n s o l e . l o g ( " R e j e c t e d " ) ; } ) ; -
Symbols Unique and immutable primitives, well suited for object properties
keys. / / S y m b o l c r e a t i o n v a r m y I D = S y m b o l ( ) ; / / S y m b o l s c a n h a v e l a b e l s ( d e b u g g i n g p u r p o s e o n l y ) v a r m y L a b e l e d I D = S y m b o l ( " l a b e l " ) ; / / S y m b o l s a r e u n i q u e S y m b o l ( ) ! = = S y m b o l ( ) / / = > t r u e / / S y m b o l s a r e i m m u t a b l e v a r m y S y m b o l = S y m b o l ( ) ; m y S y m b o l . t e s t = t r u e ; m y S y m b o l . t e s t ; / / = > u n d e f i n e d -
Symbols (Objects' keys) v a r o b j =
{ } ; v a r m y S p e c i a l S y m b o l = S y m b o l ( " l a b e l " ) ; o b j [ m y S p e c i a l S y m b o l ] = " a c c e s s u s i n g s y m b o l " ; o b j [ " l a b e l " ] = " a c c e s s u s i n g s t r i n g " ; o b j [ m y S p e c i a l S y m b o l ] ; / / = > " a c c e s s u s i n g s y m b o l " o b j [ " l a b e l " ] ; / / = > " a c c e s s u s i n g s t r i n g " -
Symbols (Almost-invisible props) v a r m y S y
m = S y m b o l ( " l a b e l " ) ; v a r o b j = { } ; o b j [ m y S y m ] = " i n v i s i b l e " ; / / I n v i s i b l e u s i n g p l a i n o l d " O b j e c t . k e y s ( ) " O b j e c t . k e y s ( o b j ) ; / / = > [ ] / / I n v i s i b l e u s i n g " f o r . . i n " l o o p f o r ( v a r x i n o b j ) { c o n s o l e . l o g ( x ) ; } / / = > / / A l t h o u g h , v i s i b l e w h e n u s i n g n e w " O b j e c t . g e t O w n P r o p e r t y S y m b o l s ( ) " O b j e c t . g e t O w n P r o p e r t y S y m b o l s ( o b j ) ; / / = > [ S y m b o l ( l a b e l ) ] -
Symbols (Some Well-known Symbols - @@iterator) / / @ @
i t e r a t o r / / M e t h o d r e t u r n i n g a n I t e r a t o r / / U s e d i n " I t e r a t i o n P r o t o c o l s " S y m b o l . i t e r a t o r Example v a r o b j = { } o b j [ S y m b o l . i t e r a t o r ] = f u n c t i o n ( ) { l e t v a l u e = 0 , m a x = 3 ; r e t u r n { n e x t : f u n c t i o n ( ) { r e t u r n { d o n e : ! ( v a l u e < m a x ) , v a l u e : v a l u e + + } ; } } ; } ; -
Symbols (Some Well-known Symbols - @@hasInstance) / / @ @
h a s I n s t a n c e / / M e t h o d o v e r r i d i n g " i n s t a n c e o f " d e f a u l t b e h a v i o u r S y m b o l . h a s I n s t a n c e Example v a r o b j = { } ; o b j [ S y m b o l . h a s I n s t a n c e ] = f u n c t i o n ( ) { c o n s o l e . w a r n ( " i n s t a n c e o f u s e d " ) ; r e t u r n f a l s e ; } ; o b j i n s t a n c e o f O b j e c t ; / / = > f a l s e / / = > w a r n ( " i n s t a n c e o f u s e d " ) -
Symbols (Some Well-known Symbols - @@isConcatSpreadable) / / @ @
i s C o n c a t S p r e a d a b l e / / B o o l e a n , c h a n g i n g " A r r a y . c o n c a t " b e h a v i o u r S y m b o l . i s C o n c a t S p r e a d a b l e Example v a r o b j = [ 4 , 5 , 6 ] ; o b j [ S y m b o l . i s C o n c a t S p r e a d a b l e ] = f a l s e ; [ 1 , 2 , 3 ] . c o n c a t ( o b j ) ; / / = > [ 1 , 2 , 3 , [ 4 , 5 , 6 ] ] -
Symbols (Some Well-known Symbols - @@species) / / @ @
s p e c i e s / / C o n s t r u c t o r M e t h o d r e t u r n i n g / / c o n s t r u c t o r u s e d i n t r a n s f o r m a t o r s l i k e " A r r a y . m a p " S y m b o l . s p e c i e s Example v a r o b j = [ ] ; o b j . c o n s t r u c t o r = { } ; o b j . c o n s t r u c t o r [ S y m b o l . s p e c i e s ] = f u n c t i o n ( ) { r e t u r n { f o o : 1 } ; } ; A r r a y . p r o t o t y p e . m a p . c a l l ( o b j , B o o l e a n ) . f o o ; / / = > 1 -
Symbols (Some Well-known Symbols - @@toPrimitive) / / @ @
t o P r i m i t i v e / / M e t h o d o v e r r i d i n g " t o P r i m i t i v e " b e h a v i o u r / / ( e g . u s e d w h e n c o e r c i o n h a p p e n s ) S y m b o l . t o P r i m i t i v e Example v a r o b j = { } ; o b j [ S y m b o l . t o P r i m i t i v e ] = f u n c t i o n ( ) { r e t u r n 4 ; } ; o b j = = 4 ; / / = > t r u e -
Symbols (Some Well-known Symbols - @@toStringTag) / / @ @
t o S t r i n g T a g / / S t r i n g o v e r r i d i n g d e f a u l t l a b e l u s e d b y " t o S t r i n g ( ) " S y m b o l . t o S t r i n g T a g Example v a r o b j = { } ; o b j [ S y m b o l . t o S t r i n g T a g ] = " S u p e r O b j e c t " ; o b j . t o S t r i n g ( ) ; / / = > [ o b j e c t S u p e r O b j e c t ] -
Map Proper implementation of key-value storages, better known as "Maps"
v a r m a p = n e w M a p ( [ [ 1 , " v a l u e " ] ] ) ; m a p . g e t ( 1 ) ; / / = > " v a l u e " m a p . s e t ( 2 , " o t h e r V a l u e " ) ; m a p . g e t ( 2 ) ; / / = > " o t h e r V a l u e " m a p . h a s ( 2 ) ; / / = > t r u e m a p . s i z e ; / / = > 2 m a p . d e l e t e ( 2 ) ; m a p . h a s ( 2 ) ; / / = > f a l s e m a p . c l e a r ( ) ; m a p . s i z e ; / / = > 0 -
Map (Everything is a Key!) With Map, objects, functions, even
NaNs can be keys. (Imposible with plain objects, because of "toString" casting) v a r m a p = n e w M a p ( ) ; v a r k e y 1 = { } ; v a r k e y 2 = { } ; v a r k e y 3 = f u n c t i o n ( ) { } ; m a p . s e t ( k e y 1 , " f i r s t " ) ; m a p . s e t ( k e y 2 , " s e c o n d " ) ; m a p . s e t ( k e y 3 , " t h i r d " ) ; m a p . g e t ( k e y 1 ) ; / / = > " f i r s t " m a p . g e t ( k e y 2 ) ; / / = > " s e c o n d " m a p . g e t ( k e y 3 ) ; / / = > " t h i r d " -
Map (Some useful methods) v a r m a p
= n e w M a p ( [ [ 1 , " f i r s t " ] , [ { } , " s e c o n d " ] ] ) ; / / I n v o k e c a l l b a c k o n e a c h e l e m e n t m a p . f o r E a c h ( c a l l b a c k ) ; / / G e t a l l k e y s ( r e t u r n s I t e r a t o r ) m a p . k e y s ( ) ; / / G e t a l l v a l u e s ( r e t u r n s I t e r a t o r ) m a p . v a l u e s ( ) ; / / G e t a l l p a i r s ( r e t u r n s I t e r a t o r ) m a p . e n t r i e s ( ) ; / / E a s y t o A r r a y c o n v e r s i o n ( t h a n k s t o S p r e a d o p e r a t o r ) [ . . . m a p . k e y s ( ) ] ; / / = > [ 1 , O b j e c t ] -
Map (The New Order) Insertion order is always preserved v
a r m a p = n e w M a p ( ) ; m a p . s e t ( { } , " f i r s t " ) ; m a p . s e t ( { } , " s e c o n d " ) ; m a p . s e t ( { } , " t h i r d " ) ; [ . . . m a p . v a l u e s ( ) ] / / = > " f i r s t " , " s e c o n d " , " t h i r d " -
WeakMap (Garbage-Collection safe brother of Map) WeakMap won't prevent objects
from being Garbage-Collected because of using them as map keys v a r m a p = n e w W e a k M a p ( ) ; { l e t k e y = { } ; m a p . s e t ( k e y , " v a l u e " ) ; } / / N o w " k e y " o b j e c t c a n b e G C ' e d s a f e l l y -
WeakMap (Private properties, anyone?) Well suited for holding private properties
of Classes (Implementation hides stored entries) / / I n s i d e a M o d u l e , o r a b l o c k . . . l e t h i d e = { } ; c l a s s M y C l a s s { c o n s t r u c t o r ( ) { t h i s . p r i v = n e w W e a k M a p ( [ [ h i d e , " s e c r e t s . . . " ] ] ) ; } m e t h o d ( ) { v a r v = t h i s . p r i v . g e t ( h i d e ) ; c o n s o l e . l o g ( v ) ; } } / / O u t s i d e . . . v a r i n s t = n e w M y C l a s s ( ) ; i n s t . p r i v . g e t ( h i d e ) ; / / = > R e f e r e n c e E r r o r : / / h i d e i s n o t d e f i n e d i n s t . m e t h o d ( ) ; / / = > " s e c r e t s . . . " -
WeakMap (Drawbacks) Only Objects (and their relatives) can be keys
No iteration possible... ...so keys have to be managed by a programmer No "clear()" method No "size" property -
Set Proper implementation of unique values storage, also known as
"Sets" v a r s e t = n e w S e t ( [ 1 , 2 , " s t r i n g " ] ) ; m a p . h a s ( 1 ) ; / / = > t r u e m a p . a d d ( " o t h e r " ) ; m a p . h a s ( " o t h e r " ) ; / / = > t r u e m a p . a d d ( " s t r i n g " ) ; / / W o n t ' d o a n y t h i n g , " s t r i n g " a l r e a d y e x i s t s m a p . d e l e t e ( " o t h e r " ) ; m a p . h a s ( " o t h e r " ) ; / / = > f a l s e m a p . s i z e ; / / = > 3 m a p . c l e a r ( ) ; m a p . s i z e / / = > 0 -
Set (Some useful methods) v a r s e t
= n e w S e t ( [ " f i r s t " , " s e c o n d " ] ) ; / / I n v o k e c a l l b a c k o n e a c h e l e m e n t m a p . f o r E a c h ( c a l l b a c k ) ; / / G e t a l l k e y s ( v a l u e s a r e a l s o k e y s ) ( r e t u r n s I t e r a t o r ) m a p . k e y s ( ) ; / / G e t a l l v a l u e s ( r e t u r n s I t e r a t o r ) m a p . v a l u e s ( ) ; / / G e t a l l p a i r s ( M a p s y m m e t r y ) ( r e t u r n s I t e r a t o r ) m a p . e n t r i e s ( ) ; / / E a s y t o A r r a y c o n v e r s i o n ( t h a n k s t o S p r e a d o p e r a t o r ) [ . . . s e t ] ; / / = > [ " f i r s t " , " s e c o n d " ] -
Set (The New Order, again...) Just like in Maps, insertion
order is preserved v a r s e t = n e w S e t ( ) ; s e t . a d d ( " f i r s t " ) ; s e t . a d d ( " s e c o n d " ) ; s e t . a d d ( " t h i r d " ) ; [ . . . s e t ] / / = > " f i r s t " , " s e c o n d " , " t h i r d " -
WeakSet (Garbage-Collection safe brother of Set) Just like WeakMaps, WeakSets
won't prevent objects from being Garbage- Collected. Useful for marking objects ("being" in set could mean that some "flag" is on) v a r s e t = n e w W e a k S e t ( ) ; { l e t v a l u e = { } ; m a p . a d d ( v a l u e ) ; } / / N o w " v a l u e " o b j e c t c a n b e G C ' e d s a f e l l y -
Typed Arrays Memory & Performance efficient binary data storages Useful
with WebGL, Cryptographics, Network Protocols etc. I n t 8 A r r a y / / 8 b i t s i g n e d i n t s U i n t 8 A r r a y / / 8 b i t u n s i g n e d i n t s U i n t 8 C l a m p e d A r r a y / / 8 b i t u n s i g n e d i n t s , c l a m p e d t o r a n g e 0 2 5 5 I n t 1 6 A r r a y / / 1 6 b i t s i g n e d i n t s U i n t 1 6 A r r a y / / 1 6 b i t u n s i g n e d i n t s I n t 3 2 A r r a y / / 3 2 b i t s i g n e t i n t s U i n t 3 2 A r r a y / / 3 2 b i t u n s i g n e d i n t s F l o a t 3 2 A r r a y / / 3 2 b i t f l o a t s F l o a t 6 4 A r r a y / / 6 4 b i t f l o a t s D a t a V i e w ( b u f f e r ) / / L o w l e v e l i n t e r f a c e p r o v i d i n g a c c e s s t o t h e b u f f e r -
Proxy Wrap around target objects' meta-operations, providing traps with custom
behaviour (like logging or validation) v a r m y T a r g e t = { p r o p : " v a l u e " } ; v a r h a n d l e r = { / / L o g e v e r y " g e t " o p e r a t i o n , / / e v e r y t h i n g e l s e i s f o r w a r d e d a s u s u a l ( n o o p s ) g e t : f u n c t i o n ( t a r g e t , n a m e ) { c o n s o l e . l o g ( " P r o p e r t y " + n a m e + " a c c e s s e d ! " ) ; r e t u r n t a r g e t [ n a m e ] ; } } ; v a r p r o x y = n e w P r o x y ( m y T a r g e t , h a n d l e r ) ; p r o x y . p r o p ; / / = > " v a l u e " / / l o g ( " P r o p e r t y p r o p a c c e s s e d ! " ) -
Proxy (Available traps) v a r h a n d
l e r = { g e t : . . . , s e t : . . . , h a s : . . . , d e l e t e P r o p e r t y : . . . , a p p l y : . . . , c o n s t r u c t : . . . , g e t O w n P r o p e r t y D e s c r i p t o r : . . . , d e f i n e P r o p e r t y : . . . , g e t P r o t o t y p e O f : . . . , s e t P r o t o t y p e O f : . . . , e n u m e r a t e : . . . , o w n K e y s : . . . , p r e v e n t E x t e n s i o n s : . . . , i s E x t e n s i b l e : . . . } -
Reflection Reverse of Proxies - call underlying object's meta-operations (Available
list of operations same as the list of Proxies' available traps) v a r o b j = { p r o p : " v a l u e " } ; / / I n v o k e d e f a u l t g e t t e r o f " p r o p " / / E q u i v a l e n t t o " o b j . p r o p " R e f l e c t . g e t ( o b j , " p r o p " ) ; / / = > " v a l u e " -
Proper Tail Calls Tail-call elimination as a Standard f u
n c t i o n f i b o n a c c i ( n , a = 0 , b = 1 ) { i f ( n = = 0 ) r e t u r n a ; i f ( n = = 1 ) r e t u r n b ; r e t u r n f i b o n a c c i ( n 1 , b , a + b ) ; } f i b o n a c c i ( 6 ) / / S u b s e q u e n t " s t a c k s " / / f i b o n a c c i ( 5 , 1 , 1 ) / / f i b o n a c c i ( 4 , 1 , 2 ) / / f i b o n a c c i ( 3 , 2 , 3 ) / / f i b o n a c c i ( 2 , 3 , 5 ) / / f i b o n a c c i ( 1 , 5 , 8 ) / / r e t u r n 8 ; / / = > 8 -
Extended Literals / / O c t a l L
i t e r a l s v a r o c t a l = 0 o 1 0 ; / / = > 8 / / B i n a r y L i t e r a l s v a r b i n a r y = 0 b 1 0 ; / / = > 2 -
Subclassing Extend your classes with Built-ins behaviour / / A
r r a y , R e g E x p & F u n c t i o n s u b c l a s s i n g c l a s s M y A r r a y e x t e n d s A r r a y { . . . } ; c l a s s M y R e g E x p e x t e n d s R e g E x p { . . . } ; c l a s s M y F u n c t i o n e x t e n d s F u n c t i o n { . . . } ; / / P r o m i s e s u b c l a s s i n g c l a s s M y P r o m i s e e x t e n d s P r o m i s e { . . . } ; / / M a p & S e t s u b c l a s s i n g c l a s s M y M a p e x t e n d s M a p { . . . } ; c l a s s M y S e t e x t e n d s S e t { . . . } ; / / P r i m i t i v e s s u b c l a s s i n g c l a s s M y B o o l e a n e x t e n d s B o o l e a n { . . . } ; c l a s s M y N u m b e r e x t e n d s N u m b e r { . . . } ; c l a s s M y S t r i n g e x t e n d s S t r i n g { . . . } ; -
Extended Standard Library (Object) / / O b j e
c t . a s s i g n ( d e s t i n a t i o n , s o u r c e 1 , s o u r c e 2 , . . . ) O b j e c t . a s s i g n ( o b j = { c : f a l s e } , { a : t r u e , b : " w o r l d " } ) ; o b j . a ; / / = > t r u e o b j . b ; / / = > " w o r l d " o b j . c ; / / = > f a l s e / / O b j e c t . i s ( l e f t , r i g h t ) O b j e c t . i s ( o b j , o b j ) ; / / = > t r u e O b j e c t . i s ( N a N , N a N ) ; / / = > t r u e / / O b j e c t . g e t O w n P r o p e r t y S y m b o l s ( o b j ) o b j [ S y m b o l ( " l a b e l " ) ] = " t e s t " ; O b j e c t . g e t O w n P r o p e r t y S y m b o l s ( o b j ) ; / / = > A r r a y [ S y m b o l ( l a b e l ) ] / / O b j e c t . s e t P r o t o t y p e O f ( o b j , p r o t o t y p e ) O b j e c t . s e t P r o t o t y p e O f ( o b j , A r r a y . p r o t o t y p e ) ; o b j i n s t a n c e o f A r r a y ; / / = > t r u e -
Extended Standard Library (String) / / S t r i
n g . p r o t o t y p e . s t a r t s W i t h ( s t r i n g ) " f o o b a r " . s t a r t s W i t h ( " f o o " ) ; / / = > t r u e / / S t r i n g . p r o t o t y p e . e n d s W i t h ( s t r i n g ) " f o o b a r " . e n d s W i t h ( " b a r " ) ; / / = > t r u e / / S t r i n g . p r o t o t y p e . i n c l u d e s ( s t r i n g ) " f o o b a r " . i n c l u d e s ( " o b a " ) ; / / = > t r u e / / S t r i n g . p r o t o t y p e . r e p e a t ( n ) " f o o " . r e p e a t ( 2 ) ; / / = > " f o o f o o " -
Extended Standard Library (Array) / / A r r a
y . p r o t o t y p e . f i n d ( p r e d i c a t e ) [ 5 , 6 , 7 ] . f i n d ( f u n c t i o n ( x ) { r e t u r n x > = 6 ; } ) ; / / = > 6 / / A r r a y . p r o t o t y p e . f i n d I n d e x ( p r e d i c a t e ) [ 5 , 6 , 7 ] . f i n d I n d e x ( f u n c t i o n ( x ) { r e t u r n x > = 6 ; } ) ; / / = > 1 / / A r r a y . p r o t o t y p e . k e y s ( ) ( r e t u r n s I t e r a t o r ) [ . . . [ 1 , 2 , 3 ] . k e y s ( ) ] ; / / = > A r r a y [ 0 , 1 , 2 ] / / A r r a y . p r o t o t y p e . v a l u e s ( ) ( r e t u r n s I t e r a t o r ) [ . . . [ 1 , 2 , 3 ] . v a l u e s ( ) ] ; / / = > A r r a y [ 1 , 2 , 3 ] -
Extended Standard Library (Number) / / N u m b
e r . i s N a N ( x ) N u m b e r . i s N a N ( 4 2 ) ; / / = > f a l s e N u m b e r . i s N a N ( N a N ) ; / / = > t r u e / / N u m b e r . i s F i n i t e ( x ) N u m b e r . i s F i n i t e ( 4 2 ) ; / / = > t r u e N u m b e r . i s F i n i t e ( I n f i n i t y ) ; / / = > f a l s e / / N u m b e r . i s S a f e I n t e g e r ( x ) N u m b e r . i s S a f e I n t e g e r ( 4 2 ) ; / / = > t r u e N u m b e r . i s S a f e I n t e g e r ( 9 0 0 7 1 9 9 2 5 4 7 4 0 9 9 2 ) ; / / = > f a l s e / / N u m b e r . E P S I L O N ( ( ( 0 . 1 + 0 . 2 ) 0 . 3 ) < N u m b e r . E P S I L O N ) ; / / = > t r u e -
Extended Standard Library (Math) / / M a t h
. t r u n c ( x ) M a t h . t r u n c ( 4 2 . 1 2 3 ) ; / / = > 4 2 / / M a t h . s i g n ( x ) M a t h . s i g n ( 4 2 ) ; / / = > 1 -
"More Sugar, Please..." As we can see, ES2015 already brings
cool new features. But it gets even better with ES2016, which is just around the corner... (Although, please note that most of the listed features are still "proposals" and "drafts", so their existence (as well as their API) may change...) -
Object.observe (Current Status: Draft) Built-in observer pattern v a r
o b j = { x : 1 } ; O b j e c t . o b s e r v e ( o b j , f u n c t i o n ( c h a n g e s ) { v a r c h a n g e d = c h a n g e s [ 0 ] ; c o n s o l e . l o g ( " C h a n g e d : " + c h a n g e d . n a m e ) ; c o n s o l e . l o g ( " C h a n g e t y p e : " + c h a n g e d . t y p e ) ; c o n s o l e . l o g ( " O l d v a l u e : " + c h a n g e d . o l d V a l u e ) ; c o n s o l e . l o g ( " N e w v a l u e : " + c h a n g e d . o b j e c t [ c h a n g e d . n a m e ] ) ; } ) ; o b j . x = 4 2 ; / / = > " C h a n g e d : x " / / = > " C h a n g e t y p e : u p d a t e " / / = > " O l d v a l u e : 1 " / / = > " N e w v a l u e : 4 2 " -
SIMD Functions (Current Status: Draft) Leverage new CPUs "Single Instruction
- Multiple Data" architectures. v a r a = S I M D . F l o a t 3 2 x 4 ( 1 , 2 , 3 , 4 ) ; v a r b = S I M D . F l o a t 3 2 x 4 ( 5 , 6 , 7 , 8 ) ; v a r c = S I M D . F l o a t 3 2 x 4 . a d d ( a , b ) ; / / = > F l o a t 3 2 x 4 [ 6 , 8 , 1 0 , 1 2 ] -
Async Functions (Current status: Proposal) No more ".then()" in your
code - "return" & "throw" only! (Seriously, do Promises can get even better than this?) / / F u n c t i o n m a r k e d a s " a s y n c " a l w a y s r e t u r n s a P r o m i s e a s y n c f u n c t i o n g e t D a t a ( u r l 1 , u r l 2 ) { / / U s e " a w a i t " k e y w o r d t o w a i t f o r o t h e r ' s P r o m i s e r e s o l u t i o n / / R e s o l u t i o n v a l u e w i l l b e s i m p l y r e t u r n e d v a r r e s u l t = a w a i t a j a x ( u r l 1 ) ; / / R e j e c t i o n o f " a w a i t e d " P r o m i s e h a p p e n s a s a n e x c e p t i o n t r y { v a r v a l u e = a w a i t a j a x ( u r l 2 ) ; } c a t c h ( e ) { c o n s o l e . e r r o r ( " C o u l d n o t f e t c h u r l 2 " ) ; } r e t u r n { d a t a : t r u e } ; / / R e s o l v e b y " r e t u r n i n g " a v a l u e . . . t h r o w { e r r o r : t r u e } ; / / . . . o r R e j e c t b y " t h r o w i n g " a n e r r o r } -
Async Functions ("await" all? No problem!) a s y n
c f u n c t i o n g e t D a t a ( u r l 1 , u r l 2 ) { v a r a j a x 1 = a j a x ( u r l 1 ) ; v a r a j a x 2 = a j a x ( u r l 2 ) ; / / " a w a i t * " o n a n A r r a y o f P r o m i s e s v a r r e s u l t s = a w a i t * [ a j a x 1 , a j a x 2 ] ; / / a l t e r n a t i v e l y , o n e c o u l d u s e P r o m i s e . a l l ( ) v a r r e s u l t s = a w a i t P r o m i s e . a l l ( [ a j a x 1 , a j a x 2 ] ) . t h e n ( f u n c t i o n ( ) { r e t u r n [ . . . a r g u m e n t s ] ; } ) ; } -
Decorators (Current status: Proposal) Modify class methods behaviour at design-time
c l a s s M y { @ l o g g e r t e s t ( ) { c o n s o l e . l o g ( " t e s t " ) ; } } f u n c t i o n l o g g e r ( t a r g e t , n a m e , d e s c r i p t o r ) { l e t o r g = d e s c r i p t o r . v a l u e ; d e s c r i p t o r . v a l u e = f u n c t i o n ( ) { c o n s o l e . l o g ( " l o g g e r " ) ; o r g ( . . . a r g u m e n t s ) ; } r e t u r n d e s c r i p t o r ; } ( n e w M y ( ) ) . t e s t ( ) ; / / = > " l o g g e r " , " t e s t " -
Decorators (Class decoration) You can also decorate the class itself
@ l o g g e r c l a s s M y { } f u n c t i o n l o g g e r ( t a r g e t ) { r e t u r n c l a s s x e x t e n d s t a r g e t { l o g ( ) { c o n s o l e . l o g ( " l o g g e d " ) ; } } ; } c o n s o l e . l o g ( ( n e w M y ( ) ) . l o g ( ) ) ; -
Object Rest & Spread (Current Status: Proposal) Apply Rest parameters
& Spread operator to objects just like in Arrays / / R e s t p r o p e r t i e s l e t { a , b , . . . c } = { a : 1 , b : 2 , x : 3 , y : 4 } ; a ; / / = > 1 b ; / / = > 2 c ; / / = > { x : 3 , y : 4 } ; / / S p r e a d p r o p e r t i e s l e t a = 1 ; l e t b = 2 ; l e t x = { c : 3 , d : 4 } ; l e t y = { a , b , . . . x } ; y ; / / = > { a : 1 , b : 2 , c : 3 , d : 4 } -
Class Properties (Current Status: Strawman - Preliminary) Properties initialization in
Class body instead of explicit initialization in constructor c l a s s M y { p r o p = 4 2 , / / P r o p e r t i e s i n i t i a l i z e d j u s t a f t e r " t h i s " i n i t i a l i z a t i o n / / s o t h e y a r e a l r e a d y v i s i b l e i n t h e c o n s t r u c t o r c o n s t r u c t o r ( ) { c o n s o l e . l o g ( t h i s . p r o p ) ; } } n e w M y ( ) ; / / = > 4 2 -
Current Browsers Support (ES2015 Support) (Based on ) Kangax Compatibility
Table Edge (IE) - 65% (no destructuring, classes, generators) Firefox 39 - 62% (old "let", no classes) Chrome 43 / Opera 30 - 44% (no destructuring, rest, spread, arrows, classes) Safari 8 - 16% (well, this is embarassing, even IE is better...) ...none of the above has modules nor subclassing yet -
Upcoming Browsers Support (ES2015 Support) Firefox 42 - 67% (mostly
minor features + ES2016 SIMD support) Chrome 45 / Opera 32 - 61% (added rest, spread, arrows and some other minor features) ...still no modules support -
But Wait... There Is ! Babel "Babel is a JavaScript
compiler." Because most of the new features are actually implementable using ES5 code, it is possible to compile ES2015 to the old standard, enabling new features to all the browsers right now... As for now, Babel has 71% of ES2015 support & 71% of ES2016 support (Pre- strawman not includes) Other notable compilers with decent ES2015 support are: (58%) and (52%). Traceur Type-Script -
What about Node.js & io.js? According to , Node.js has
17% (although most of the new features are hidden behind "--harmony" flag), and io.js has 39% (and again, some features are hidden behind a flag). Kangax Compatibility Table But because of Babel & other compilers, effective support is much much higher... -
Thank You! Sources - - - - - - -
Own adventures Mozilla Developer Network ②ality.com (by Axel Rauschmayer) Exploring ES6 (by Axel Rauschmayer) Babel's "Learn ES2015" lukehoban/es6features Kangax ES2015/ES2016 Compatibility Table