Welcome our new ES5 Overlords

23fc4556be14017796d38579dd4778ab?s=47 Mike MacCana
September 12, 2013

Welcome our new ES5 Overlords

While we constantly pay attention to new utility libraries, MVC frameworks, and other well-publicised tools, most of our non-library coding hasn’t changed since ES3.

We’re missing out: beyond the obvious, there’s a world of interesting stuff you can and should be doing with ES5: safe extension of inbuilt methods, mechanisms for live binding data and DOM, and a whole host of techniques to make your code shorter and more readable. Best of all, it’s already built into your browser and node.

23fc4556be14017796d38579dd4778ab?s=128

Mike MacCana

September 12, 2013
Tweet

Transcript

  1. 2.
  2. 3.

    A good time to talk about ES5 Every current browser

    supports ES5 Every previous generation browser supports ES5 In a few weeks every browser before that will support ES5 Node is ES5 IE8 may not be a requirement in your next project
  3. 6.

    Some JS A list of German bands Clicking the button

    should show the band name v a r b a n d s = [ ' A p p a r a t ' , ' B o y ' , ' K r a f t k l u b ' ] ; f o r ( v a r i = 0 ; i < b a n d s . l e n g t h ; i + + ) { v a r b a n d = b a n d s [ i ] , b u t t o n = d o c u m e n t . c r e a t e E l e m e n t ( ' b u t t o n ' ) ; b u t t o n . a p p e n d C h i l d ( d o c u m e n t . c r e a t e T e x t N o d e ( b a n d ) ) ; b u t t o n . a d d E v e n t L i s t e n e r ( ' c l i c k ' , f u n c t i o n ( ) { a l e r t ( b a n d ) ; } ) ; d o c u m e n t . b o d y . a p p e n d C h i l d ( b u t t o n ) ; }
  4. 7.

    This code has two problems Valeska from 'Boy' is actually

    Swiss When the loop is finished, 'band' has the last value, and that's what the inner function 'sees'.
  5. 9.

    Some basic JS (fixed) v a r b a n

    d s = [ ' A p p a r a t ' , ' B o y ' , ' K r a f t k l u b ' ] ; f o r ( v a r i = 0 ; i < b a n d s . l e n g t h ; i + + ) { v a r b a n d = b a n d s [ i ] , b u t t o n = d o c u m e n t . c r e a t e E l e m e n t ( ' b u t t o n ' ) ; b u t t o n . a p p e n d C h i l d ( d o c u m e n t . c r e a t e T e x t N o d e ( b a n d ) ) ; ( f u n c t i o n ( b a n d ) { b u t t o n . a d d E v e n t L i s t e n e r ( ' c l i c k ' , f u n c t i o n ( ) { a l e r t ( b a n d ) ; } ) ; } ) ( b a n d ) ; d o c u m e n t . b o d y . a p p e n d C h i l d ( b u t t o n ) ; }
  6. 10.

    Same thing in ES5 [ ' A p p a

    r a t ' , ' B o y ' , ' K r a f t k l u b ' ] . f o r E a c h ( f u n c t i o n ( b a n d ) { v a r b u t t o n = d o c u m e n t . c r e a t e E l e m e n t ( ' b u t t o n ' ) ; b u t t o n . a p p e n d C h i l d ( d o c u m e n t . c r e a t e T e x t N o d e ( b a n d ) ) ; b u t t o n . a d d E v e n t L i s t e n e r ( ' c l i c k ' , f u n c t i o n ( ) { a l e r t ( b a n d ) ; } ) ; d o c u m e n t . b o d y . a p p e n d C h i l d ( b u t t o n ) ; } )
  7. 16.

    ES3: Non-native methods appear during iteration O b j e

    c t . p r o t o t y p e . o l d S t y l e M e t h o d = f u n c t i o n o l d S t y l e M e t h o d ( ) { } ; v a r s o m e O b j e c t = { } ; f o r ( v a r k e y i n s o m e O b j e c t ) { c o n s o l e . l o g ( k e y ) } ;
  8. 17.

    ES3: But native methods don't This is why toString() doesn't

    appear in 'for' loops. c o n s o l e . l o g ( O b j e c t . p r o t o t y p e . t o S t r i n g ) ; f u n c t i o n t o S t r i n g ( ) { [ n a t i v e c o d e ] } ;
  9. 18.

    Added methods are always enumerable in ES3 So they always

    appear in 'for' loops Extending prototypes in ES3 can work if the entire universe changes their 'for' loops Surprisingly this not happen So extending prototypes in ES3 is risky
  10. 19.

    ES5: Non enumerable methods can be added Requires native ES5

    (not shimmable) O b j e c t . d e f i n e P r o p e r t y ( O b j e c t . p r o t o t y p e , " n e w S t y l e M e t h o d " , { v a l u e : f u n c t i o n n e w S t y l e M e t h o d ( ) { } , e n u m e r a b l e : f a l s e } ) ; f o r ( v a r k e y i n s o m e O b j e c t ) { c o n s o l e . l o g ( k e y ) } ;
  11. 24.

    Underscore Agave (ES5 only) Sugar Methods No Yes Yes Regular

    'for' loops Yes Yes No Conflict-free Yes Yes No
  12. 26.

    Other reasons: "You can do that. You should do that."

    Brendan Eich, JQuery UK, 19 Apr 2013 Ember does it. Ember JS Prototype Extensions I just gave you a happy hippo and now we are friends.
  13. 28.

    An experiment in two parts 1. A data → DOM

    binding (I like mustache, so I use Ractive). 2. Data changes applied to binding live via object.defineProperty()
  14. 29.

    Live binding with defineProperty v a r l i v

    e b i n d = f u n c t i o n ( o b j e c t , b i n d i n g , p r o p e r t i e s ) { p r o p e r t i e s . f o r E a c h ( f u n c t i o n ( p r o p e r t y ) { v a r h i d d e n P r o p e r t y = ' _ ' + p r o p e r t y O b j e c t . d e f i n e P r o p e r t y ( o b j e c t , p r o p e r t y , { g e t : f u n c t i o n ( ) { r e t u r n t e s t D a t a [ h i d d e n P r o p e r t y ] ; } , s e t : f u n c t i o n ( n e w V a l u e ) { t e s t D a t a [ h i d d e n P r o p e r t y ] = n e w V a l u e ; b i n d i n g . s e t ( p r o p e r t y , n e w V a l u e ) } , e n u m e r a b l e : t r u e , c o n f i g u r a b l e : t r u e } ) ; } ) }
  15. 30.

    Note 1. This is an experiment 2. We also use

    prototype chain injection (see links) for array.length magic
  16. 31.

    ES5-only is coming For many, it's already here Use ES5

    methods directly Don't be scared to extend native prototypes Experiment