-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchapter13.html
More file actions
1149 lines (961 loc) · 57.2 KB
/
chapter13.html
File metadata and controls
1149 lines (961 loc) · 57.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Learning React - Appendix - ES6 features</title>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="icon" type="image/x-icon" href="mc2/images/favicon.ico">
<link rel="stylesheet" href="mc2/styles/reveal.css">
<link rel="stylesheet" href="mc2/styles/theme.css" id="theme">
<link rel="stylesheet" href="mc2/styles/code.css">
<link rel="stylesheet" href="styles/react.css">
</head>
<body>
<div id="pos"></div>
<div class="reveal">
<div class="slides">
<section class="slide chaptertitle">
<div class="slidecontent">
<div class="chapternumber"> chapter 13 of 14 </div>
<h1>Appendix - ES6 features</h1>
<span>The nitty gritty</span>
</div>
</section>
<section class="slide sectionlist">
<div class="slidecontent">
<h3>Sections in this chapter</h3>
<ol>
<li><a href="#/2">Versatile object definitions</a></li>
<li><a href="#/3">Destructuring and rest</a></li>
<li><a href="#/4">Versatile function definitions</a></li>
<li><a href="#/5">Spreads</a></li>
<li><a href="#/6">Modules</a></li>
<li><a href="#/7">Classes</a></li>
<li><a href="#/8">Decorators</a></li>
<li><a href="#/9">Miscellaneous</a></li>
<li><a href="#/10">Exercise ‑ trying it out</a></li>
</ol>
</div>
</section>
<section>
<section class="slide sectiontitle">
<div class="slidecontent">
<div class='sectioncount'>Section 1/9</div>
<h3>Versatile object definitions</h3>
<p>defining objects like a boss</p>
</div>
</section>
<section class="slide list" data-pos="13-1-1">
<span class="pos">13-1-1</span>
<div class="slidecontent">
<p>In ES2015 we got five small but nice features for <strong>defining objects in a smoother way</strong>:</p>
<ul>
<li><span>a</span>dynamic keys</li>
<li><span>b</span>automatic same-key-value</li>
<li><span>c</span>method shorthand</li>
<li><span>d</span>getters</li>
<li><span>e</span>setters</li>
</ul>
</div></section>
<section class="slide num numA" data-pos="13-1-2">
<span class="pos">13-1-2</span>
<div class="slidecontent">
<p>If we wanted to create an <strong>object with a dynamic key</strong> we had to go about it in a roundabout way before:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> obj = {};
obj[dynamicKey] = someValue;
</code></pre>
</div></section>
<section class="slide" data-pos="13-1-3">
<span class="pos">13-1-3</span>
<div class="slidecontent"><p>Now, instead, we can use the <strong>dynamic key syntax</strong> by wrapping it in brackets:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> obj = {[dynamicKey]: someValue};
</code></pre>
</div></section>
<section class="slide num numB" data-pos="13-1-4">
<span class="pos">13-1-4</span>
<div class="slidecontent">
<p>Also, if our value is in a <strong>variable with the same name as the intended key</strong>, like here:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> person = {
<span class="hljs-attr">name</span>: name,
<span class="hljs-attr">age</span>: age
};
</code></pre>
</div></section>
<section class="slide" data-pos="13-1-5">
<span class="pos">13-1-5</span>
<div class="slidecontent"><p>...ES2015 introduces a <strong>shorthand syntax</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> person = {name, age};
</code></pre>
</div></section>
<section class="slide num numC" data-pos="13-1-6">
<span class="pos">13-1-6</span>
<div class="slidecontent">
<p>And if we define an <strong>object with a method</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> obj = {
<span class="hljs-attr">method</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">arg1,arg2</span>)</span>{
<span class="hljs-comment">// do advanced stuff</span>
}
};
</code></pre>
</div></section>
<section class="slide" data-pos="13-1-7">
<span class="pos">13-1-7</span>
<div class="slidecontent"><p>...ES2015 lets us be less verbose by using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">method shorthand syntax</a>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> obj = {
method(arg1,arg2){
<span class="hljs-comment">// do advanced stuff</span>
}
};
</code></pre>
</div></section>
<section class="slide" data-pos="13-1-8">
<span class="pos">13-1-8</span>
<div class="slidecontent"><p>This can also be <strong>combined with the dynamic key syntax</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> obj = {
[methodName](arg1,arg2){
<span class="hljs-comment">// do advanced stuff</span>
}
};
</code></pre>
</div></section>
<section class="slide num numD" data-pos="13-1-9">
<span class="pos">13-1-9</span>
<div class="slidecontent">
<p>Finally, ES2015 also introduced <strong>getters and setters</strong>.</p>
<p>Let's look at <strong>getters</strong> first. They are very useful for dealing with <strong>computed properties</strong>.</p>
</div></section>
<section class="slide" data-pos="13-1-10">
<span class="pos">13-1-10</span>
<div class="slidecontent"><p>Say we're working with <strong>user objects</strong> like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> user = {
<span class="hljs-attr">firstName</span>: <span class="hljs-string">"John"</span>,
<span class="hljs-attr">lastName</span>: <span class="hljs-string">"Doe"</span>
};
</code></pre>
<p>Now we want to implement a <strong>computed property <code>fullName</code></strong>.</p>
</div></section>
<section class="slide" data-pos="13-1-11">
<span class="pos">13-1-11</span>
<div class="slidecontent"><p>Here's an <strong>ES3 solution</strong> doing it as a <strong>method</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> user = {
<span class="hljs-attr">firstName</span>: <span class="hljs-string">"John"</span>,
<span class="hljs-attr">lastName</span>: <span class="hljs-string">"Doe"</span>,
<span class="hljs-attr">fullName</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.firstName + <span class="hljs-string">' '</span> + <span class="hljs-keyword">this</span>.lastName;
}
}
user.fullName(); <span class="hljs-comment">// John Doe</span>
</code></pre>
</div></section>
<section class="slide" data-pos="13-1-12">
<span class="pos">13-1-12</span>
<div class="slidecontent"><p>By using an <strong>ES2015 getter</strong> we can access the computed property normally instead:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> user = {
<span class="hljs-attr">firstName</span>: <span class="hljs-string">"John"</span>,
<span class="hljs-attr">lastName</span>: <span class="hljs-string">"Doe"</span>,
get fullName() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.firstName + <span class="hljs-string">' '</span> + <span class="hljs-keyword">this</span>.lastName;
}
}
user.fullName; <span class="hljs-comment">// John Doe, without invocation!</span>
</code></pre>
<p>Cf. <a href="https://en.wikipedia.org/wiki/Uniform_access_principle">uniform access principle</a>.</p>
</div></section>
<section class="slide num numE" data-pos="13-1-13">
<span class="pos">13-1-13</span>
<div class="slidecontent">
<p>A <strong>setter</strong> let's you <strong>act upon prop mutation</strong>, for example <strong>logging</strong>...</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> user = {
set userName(str) {
log(<span class="hljs-keyword">this</span>._userName + <span class="hljs-string">" changed name to "</span> + str);
<span class="hljs-keyword">this</span>._userName = str;
}
}
user.userName = <span class="hljs-string">"Steve"</span>; <span class="hljs-comment">// Bob changed name to Steve</span>
</code></pre>
</div></section>
<section class="slide" data-pos="13-1-14">
<span class="pos">13-1-14</span>
<div class="slidecontent"><p>...or <strong>validation</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> user = {
set userName(str) {
<span class="hljs-keyword">if</span> (str.match(<span class="hljs-regexp">/[^a-z]/</span>)){
<span class="hljs-keyword">throw</span> <span class="hljs-string">"Name can only contain lowercase letters!"</span>;
}
<span class="hljs-keyword">this</span>._userName = str;
}
}
user.userName = <span class="hljs-string">"Bob the 1 and only"</span>; <span class="hljs-comment">// Name can only contain..</span>
</code></pre>
</div></section>
<section class="slide question" data-pos="13-1-15">
<span class="pos">13-1-15</span>
<div class="slidecontent">
<p>Did you note that we used a <strong>different property name</strong> inside the setter? The setter was for <code>userName</code>, but inside it we instead set <code>_userName</code>.</p>
<p>Why do you think that is?</p>
</div></section>
<section class="slide answer" data-pos="13-1-16">
<span class="pos">13-1-16</span>
<div class="slidecontent">
<p>If we mutated the same property inside the setter then that would trigger the setter to be called, which would mutate the property, which would trigger the setter, etc. We would end up in an <strong>infinite loop</strong>.</p>
</div></section>
</section>
<section>
<section class="slide sectiontitle">
<div class="slidecontent">
<div class='sectioncount'>Section 2/9</div>
<h3>Destructuring and rest</h3>
<p>cherry-picking the raisins from the cookie</p>
</div>
</section>
<section class="slide" data-pos="13-2-1">
<span class="pos">13-2-1</span>
<div class="slidecontent"><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Destructuring</a> is a way to pick values from nested structures without having to do the manual digging.</p>
</div></section>
<section class="slide" data-pos="13-2-2">
<span class="pos">13-2-2</span>
<div class="slidecontent"><p>Let's say we have an <strong>array of <code>contenders</code></strong>, each represented by an object.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> contenders = [
{<span class="hljs-attr">name</span>: <span class="hljs-string">"David"</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">37</span>},
{<span class="hljs-attr">name</span>: <span class="hljs-string">"Carl"</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">38</span>}
<span class="hljs-comment">/* and a few others */</span>
];
</code></pre>
<p>They are <strong>sorted by position</strong> so the first contender won, etc.</p>
</div></section>
<section class="slide" data-pos="13-2-3">
<span class="pos">13-2-3</span>
<div class="slidecontent"><p>If we wanted the <strong>name of the winner</strong> we would do something like this in ES5:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> winnersName = contenders[<span class="hljs-number">0</span>].name;
</code></pre>
</div></section>
<section class="slide" data-pos="13-2-4">
<span class="pos">13-2-4</span>
<div class="slidecontent"><p>With <strong>destructuring</strong>, we can instead do this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> [{<span class="hljs-attr">name</span>: winnersName}] = contenders;
</code></pre>
<p>Or, combined with the <strong>same-key-value shorthand</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> [{name}] = contenders;
</code></pre>
</div></section>
<section class="slide" data-pos="13-2-5">
<span class="pos">13-2-5</span>
<div class="slidecontent"><p>Destructuring also allows us to use the powerful <strong>rest</strong> element which can <strong>lump up many array elements into one</strong>, making for some very succinct code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> [winner, ...losers] = contenders;
</code></pre>
</div></section>
<section class="slide" data-pos="13-2-6">
<span class="pos">13-2-6</span>
<div class="slidecontent"><p>Note that the rest element <strong>has to be the last one in the array</strong>, so this wouldn't work:</p>
<pre><code><span class="hljs-keyword">let</span> [...others, superloser] = contenders; <span class="hljs-comment">// syntax error</span>
</code></pre></div></section>
<section class="slide question" data-pos="13-2-7">
<span class="pos">13-2-7</span>
<div class="slidecontent">
<p>Wait.. Theoretically, <strong>the rest could be placed <em>anywhere</em></strong>, as long as there's just one. The parser should still be able to figure out what's what!</p>
<p>Right?</p>
</div></section>
<section class="slide answer" data-pos="13-2-8">
<span class="pos">13-2-8</span>
<div class="slidecontent">
<p>True. But that would <strong>require lookahead</strong>, which is <strong>complex and more taxing</strong>. And so the choice was made to only allow the rest element in the last position.</p>
</div></section>
</section>
<section>
<section class="slide sectiontitle">
<div class="slidecontent">
<div class='sectioncount'>Section 3/9</div>
<h3>Versatile function definitions</h3>
<p>defining function like a boss</p>
</div>
</section>
<section class="slide list" data-pos="13-3-1">
<span class="pos">13-3-1</span>
<div class="slidecontent">
<p>ES2015 provides <strong>several neat features for defining functions</strong>:</p>
<ul>
<li><span>a</span>default parameter values</li>
<li><span>b</span>rest parameters</li>
<li><span>c</span>destructuring parameters</li>
<li><span>d</span>arrow functions</li>
</ul>
</div></section>
<section class="slide num numA" data-pos="13-3-2">
<span class="pos">13-3-2</span>
<div class="slidecontent">
<p><strong>Default parameter values</strong> exist in many languages, and was popularized in JS through <a href="">CoffeeScript</a>.</p>
<p>The idea is to <strong>handle optional parameters</strong> in a smoother way.</p>
</div></section>
<section class="slide" data-pos="13-3-3">
<span class="pos">13-3-3</span>
<div class="slidecontent"><p>Creating a <strong>function with an optional parameter</strong> in ES3 meant we had to do a sometimes tedious dance of initialization:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">makePerson</span>(<span class="hljs-params">name, age</span>) </span>{
<span class="hljs-keyword">var</span> age = age || <span class="hljs-string">'unknown'</span>;
<span class="hljs-comment">// do complex stuff</span>
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-3-4">
<span class="pos">13-3-4</span>
<div class="slidecontent"><p>With <strong>default parameter values</strong> we can instead do this: </p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">makePerson</span>(<span class="hljs-params">name, age = <span class="hljs-string">'unknown'</span></span>) </span>{
<span class="hljs-comment">// do complex stuff</span>
}
</code></pre>
</div></section>
<section class="slide num numB" data-pos="13-3-5">
<span class="pos">13-3-5</span>
<div class="slidecontent">
<p>The second new feature, <strong>rest parameters</strong>, is a way of capturing multiple arguments into a single variable like a rest element in a destructuring.</p>
<p>This can often save us from having to do awkward stuff with the not-quite-an-array <code>arguments</code> object.</p>
</div></section>
<section class="slide" data-pos="13-3-6">
<span class="pos">13-3-6</span>
<div class="slidecontent"><p>Imagine a <code>competition</code> function that is called with all contenders one by one:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">competition</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">var</span> contenders = <span class="hljs-built_in">Array</span>.prototype.slice.call(<span class="hljs-built_in">arguments</span>);
<span class="hljs-keyword">var</span> winner = contenders[<span class="hljs-number">0</span>];
<span class="hljs-keyword">var</span> losers = contenders.slice(<span class="hljs-number">1</span>);
<span class="hljs-comment">// do something with winner and losers</span>
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-3-7">
<span class="pos">13-3-7</span>
<div class="slidecontent"><p>Using rest parameters, this function simply becomes:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">competition</span>(<span class="hljs-params">winner, ...losers</span>) </span>{
<span class="hljs-comment">// do something with winner and losers</span>
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-3-8">
<span class="pos">13-3-8</span>
<div class="slidecontent"><p>Note that the rest parameter <strong>has to be the last parameter</strong>, just like the rest element, and for the same reason.</p>
</div></section>
<section class="slide num numC" data-pos="13-3-9">
<span class="pos">13-3-9</span>
<div class="slidecontent">
<p>Remember <strong>destructuring</strong>? We can <strong>use that in signatures</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">introduce</span>(<span class="hljs-params">{name, age}</span>) </span>{
<span class="hljs-built_in">console</span>.log(name,<span class="hljs-string">"is"</span>,age,<span class="hljs-string">"years old"</span>);
}
<span class="hljs-keyword">var</span> me = {<span class="hljs-attr">name</span>: <span class="hljs-string">"David"</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">37</span>};
introduce(me); <span class="hljs-comment">// David is 37 years old</span>
</code></pre>
</div></section>
<section class="slide num numD" data-pos="13-3-10">
<span class="pos">13-3-10</span>
<div class="slidecontent">
<p>Finally - know how <strong>defining anonymous functions</strong> in JS is rather verbose?</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> mcboatify = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">arg</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-string">"Boaty Mc"</span>+arg+<span class="hljs-string">"Face"</span>;
};
</code></pre>
</div></section>
<section class="slide" data-pos="13-3-11">
<span class="pos">13-3-11</span>
<div class="slidecontent"><p>With <strong>arrow functions</strong> things feel less heavy:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> mcboatify = <span class="hljs-function">(<span class="hljs-params">arg</span>) =></span> {
<span class="hljs-keyword">return</span> <span class="hljs-string">"Boaty Mc"</span> + arg + <span class="hljs-string">"Face"</span>;
};
</code></pre>
</div></section>
<section class="slide" data-pos="13-3-12">
<span class="pos">13-3-12</span>
<div class="slidecontent"><p>They can become smaller still - if we have <strong>exactly one parameter</strong>, we can <strong>omit the parenthesis</strong> in the signature:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> mcboatify = <span class="hljs-function"><span class="hljs-params">arg</span> =></span> {
<span class="hljs-keyword">return</span> <span class="hljs-string">"Boaty Mc"</span> + arg + <span class="hljs-string">"Face"</span>;
};
</code></pre>
</div></section>
<section class="slide" data-pos="13-3-13">
<span class="pos">13-3-13</span>
<div class="slidecontent"><p>Finally, if you <strong>just want to return an expression</strong>, we can <strong>skip brackets and the return keyword</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> mcboatify = <span class="hljs-function"><span class="hljs-params">arg</span> =></span> <span class="hljs-string">"Boaty Mc"</span> + arg + <span class="hljs-string">"Face"</span>;
</code></pre>
<p>Now the function body consists of a single expression, which will be implicitly returned.</p>
</div></section>
<section class="slide" data-pos="13-3-14">
<span class="pos">13-3-14</span>
<div class="slidecontent"><p>Note however that if you want to use the <strong>single expression form with an object literal</strong>, we have to <strong>wrap it in parenthesis</strong> to distinguish it from a regular function block:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> createUser = <span class="hljs-function">(<span class="hljs-params">name,age</span>)=></span> ({name,age})
</code></pre>
</div></section>
<section class="slide" data-pos="13-3-15">
<span class="pos">13-3-15</span>
<div class="slidecontent"><p>Arrow functions are not only less heavy to write, they are also lighter for the interpreter since they <strong>don't get an implicit context parameter</strong>.</p>
</div></section>
<section class="slide" data-pos="13-3-16">
<span class="pos">13-3-16</span>
<div class="slidecontent"><p>Which means that if you refer to <code>this</code> inside an arrow function, it is the <strong>same <code>this</code> as on the outside</strong>.</p>
<pre><code><span class="hljs-keyword">var</span> me = <span class="hljs-keyword">this</span>;
setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =></span> {
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span> === me); <span class="hljs-comment">// true</span>
}, <span class="hljs-number">10</span>);
setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span> === me); <span class="hljs-comment">// false</span>
}, <span class="hljs-number">10</span>);
</code></pre></div></section>
<section class="slide" data-pos="13-3-17">
<span class="pos">13-3-17</span>
<div class="slidecontent"><p>As a final note; arrow functions can beautifully describe the flow for <strong>nested higher order callbacks</strong>. Take this convoluted old code:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiplier</span>(<span class="hljs-params">func,times</span>)</span>{
<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < times; i = i + <span class="hljs-number">1</span>){
func();
}
};
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-3-18">
<span class="pos">13-3-18</span>
<div class="slidecontent"><p>With arrow functions, that becomes:</p>
<pre><code><span class="hljs-keyword">var</span> multiplier = (<span class="hljs-function"><span class="hljs-keyword">func</span>,<span class="hljs-title">times</span>)=> <span class="hljs-params">()</span></span>=> {
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < times; i = i + <span class="hljs-number">1</span>){
<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span>;
}
}
</code></pre></div></section>
</section>
<section>
<section class="slide sectiontitle">
<div class="slidecontent">
<div class='sectioncount'>Section 4/9</div>
<h3>Spreads</h3>
<p>the dark side of rests</p>
</div>
</section>
<section class="slide" data-pos="13-4-1">
<span class="pos">13-4-1</span>
<div class="slidecontent"><p>You have already seen how we use <strong>rest</strong> element/parameter to capture several array elements into a single variable:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> [winner, ...losers] = competitors;
</code></pre>
</div></section>
<section class="slide" data-pos="13-4-2">
<span class="pos">13-4-2</span>
<div class="slidecontent"><p>Now imagine <strong>the opposite scenario</strong> - we have the <code>winner</code> and <code>losers</code> variables, and want to define <code>competitors</code>. In ES3 this is done like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> competitors = [winner].concat(losers);
</code></pre>
</div></section>
<section class="slide" data-pos="13-4-3">
<span class="pos">13-4-3</span>
<div class="slidecontent"><p>ES2015 gives us a new options - <strong>spreads</strong>! It looks exactly like rest, but we use it on the <em>right side</em> instead (or when we <em>call</em> a function as opposed to when we define it):</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> competitors = [winner, ...losers];
</code></pre>
<p>We say that we <em>spread</em> the contents of the expression into the outer array.</p>
</div></section>
<section class="slide" data-pos="13-4-4">
<span class="pos">13-4-4</span>
<div class="slidecontent"><p>Spreads gives us a less verbose way to <strong>copy an object and add properties to it</strong>, which is otherwise done like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> augmentedObj = <span class="hljs-built_in">Object</span>.assign({}, oldObj, newProps);
</code></pre>
</div></section>
<section class="slide" data-pos="13-4-5">
<span class="pos">13-4-5</span>
<div class="slidecontent"><p>With spreads we can instead do this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> augmentedObj = {...oldObj, ...newProps};
</code></pre>
</div></section>
<section class="slide" data-pos="13-4-6">
<span class="pos">13-4-6</span>
<div class="slidecontent"><p>Note that while spreads and rests <em>with arrays</em> are in the spec for ES2015, <strong>object spread is still a Stage 3 proposal</strong> (November 2017).</p>
<p>It is <strong>expected to be accepted into an upcoming release</strong> of the language, and is already supported by Babel and the like.</p>
</div></section>
</section>
<section>
<section class="slide sectiontitle">
<div class="slidecontent">
<div class='sectioncount'>Section 5/9</div>
<h3>Modules</h3>
<p>getting into the import/export business</p>
</div>
</section>
<section class="slide" data-pos="13-5-1">
<span class="pos">13-5-1</span>
<div class="slidecontent"><p><strong>Node gave us modules</strong> through the <code>require</code> and <code>module.exports</code> globals it provides.</p>
<p>But with ES2015, we got <strong>native modules</strong> for the very first time!</p>
</div></section>
<section class="slide" data-pos="13-5-2">
<span class="pos">13-5-2</span>
<div class="slidecontent"><p>While <strong>Node modules</strong> followed the <strong>CommonJS module standard</strong>, what was implemented in the language follows <strong>another syntax</strong>, named <strong>ES modules</strong>.</p>
<p>But the <strong>concepts are the same</strong>. While you would do this in <strong>CommonJS</strong>...</p>
<pre><code>// file1.js
module.exports = <span class="hljs-meta">{..}</span>;
//file2.js
<span class="hljs-keyword">var</span> lib = require(<span class="hljs-string">"./file1.js"</span>);
</code></pre></div></section>
<section class="slide" data-pos="13-5-3">
<span class="pos">13-5-3</span>
<div class="slidecontent"><p>...you would do this with <strong>ES modules</strong>:</p>
<pre><code>// file1.js
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> lib = <span class="hljs-meta">{..}</span>;
//file2.js
<span class="hljs-keyword">import</span> lib <span class="hljs-keyword">from</span> './file1.js'
</code></pre><p>We have to <strong>name our exports</strong> here, otherwise things are <strong>pretty similar</strong>.</p>
</div></section>
<section class="slide" data-pos="13-5-4">
<span class="pos">13-5-4</span>
<div class="slidecontent"><p>There are <strong>other differences too</strong>, so for the full scope you should <strong>check the MDN docs</strong> for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import">import</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export">export</a></p>
</div></section>
<section class="slide" data-pos="13-5-5">
<span class="pos">13-5-5</span>
<div class="slidecontent"><p>Note that even though this is now <strong>part of the language</strong>, there are <strong>no browsers that implement the functionality yet</strong>.</p>
<p>This is mainly because it <strong>wouldn't be practical</strong> - we'd get a <strong>gazillion http requests for small files</strong>.</p>
</div></section>
<section class="slide" data-pos="13-5-6">
<span class="pos">13-5-6</span>
<div class="slidecontent"><p>And since we <strong>likely have a build step anyway</strong> to do minification and transpiling and similar, you can easily <strong>bundle your code into a single file</strong>, too.</p>
<p>But, with the advent of HTTP2, <strong>who knows what the future will hold</strong>!</p>
</div></section>
</section>
<section>
<section class="slide sectiontitle">
<div class="slidecontent">
<div class='sectioncount'>Section 6/9</div>
<h3>Classes</h3>
<p>Waiter, there are classes in my JS!</p>
</div>
</section>
<section class="slide" data-pos="13-6-1">
<span class="pos">13-6-1</span>
<div class="slidecontent"><p>Before ES2015, JavaScript used to famously <strong>lack classes</strong>.</p>
<p>This was <strong>not an oversight</strong>. Consider what <strong>classes are normally used for</strong>:</p>
<ul>
<li><strong>reusing functionality</strong> and </li>
<li>setting up <strong>hierarchies</strong></li>
</ul>
</div></section>
<section class="slide" data-pos="13-6-2">
<span class="pos">13-6-2</span>
<div class="slidecontent"><p>In <strong>JavaScript</strong> this is addressed by</p>
<ul>
<li>simply <strong>grabbing methods</strong> and/or <strong>mixing objects</strong></li>
<li><strong>prototypal "inheritance"</strong>, which should really be called delegation</li>
</ul>
</div></section>
<section class="slide" data-pos="13-6-3">
<span class="pos">13-6-3</span>
<div class="slidecontent"><p>This means that <strong>classes didn't really serve a purpose</strong>. Yet they were <strong>still frequently used</strong>, through the weird, bolted-on <strong><code>new</code></strong> syntax which <strong>makes functions behave like constructors</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> user = <span class="hljs-keyword">new</span> User(<span class="hljs-string">"David"</span>, <span class="hljs-number">1979</span>);
</code></pre>
</div></section>
<section class="slide" data-pos="13-6-4">
<span class="pos">13-6-4</span>
<div class="slidecontent"><p>But to really make this <strong>behave like normal classes</strong>...</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> lucas = <span class="hljs-keyword">new</span> Dog(<span class="hljs-string">"Lucas"</span>);
lucas instanceOf Dog; <span class="hljs-comment">// true</span>
lucas instanceOf Animal; <span class="hljs-comment">// true</span>
lucas.bark(); <span class="hljs-comment">// Lucas goes woof!</span>
</code></pre>
</div></section>
<section class="slide" data-pos="13-6-5">
<span class="pos">13-6-5</span>
<div class="slidecontent"><p>...then lots of <strong>jumping through hoops</strong> had to be done:</p>
<pre><code class="lang-javascript">Dog.prototype = <span class="hljs-keyword">new</span> Animal();
Dog.prototype.constructor = Animal;
Dog.prototype.bark = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.name, <span class="hljs-string">"goes woof!"</span>);
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-6-6">
<span class="pos">13-6-6</span>
<div class="slidecontent"><p>To <strong>facilitate "class" use</strong> in JavaScript, <strong>ES2015 introduced the <code>class</code></strong> syntax:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
bark() {
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.name, <span class="hljs-string">"goes woof!"</span>);
}
}
</code></pre>
<p>Note how <strong>method shorthands</strong> are available in class declarations too!</p>
</div></section>
<section class="slide" data-pos="13-6-7">
<span class="pos">13-6-7</span>
<div class="slidecontent"><p>But it is important to note that this does <strong>not mean that JavaScript has actual classes</strong>.</p>
<p>Under the hood the same weird <code>prototype</code> and <code>constructor</code> dance happens.</p>
</div></section>
<section class="slide list" data-pos="13-6-8">
<span class="pos">13-6-8</span>
<div class="slidecontent">
<p>Still, since the <strong>syntax hides the mismatch</strong>, it can be a <strong>convenient way to package functionality</strong>. Specifically:</p>
<ul>
<li><span>a</span>constructor</li>
<li><span>b</span>methods</li>
<li><span>c</span>properties</li>
</ul>
</div></section>
<section class="slide num numA" data-pos="13-6-9">
<span class="pos">13-6-9</span>
<div class="slidecontent">
<p>First off, what <strong>used to go in the fake constructor</strong>...</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Animal</span>(<span class="hljs-params">name</span>) </span>{
<span class="hljs-keyword">this</span>.name = name;
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-6-10">
<span class="pos">13-6-10</span>
<div class="slidecontent"><p>...is now placed in a literal <strong><code>constructor</code> method</strong> in the class declaration:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
<span class="hljs-keyword">constructor</span>(name) {
<span class="hljs-keyword">this</span>.name = name;
}
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-6-11">
<span class="pos">13-6-11</span>
<div class="slidecontent"><p>If you want <strong>the inherited constructor to be invoked too</strong>, you must <strong>do so yourself</strong> with the new <strong><code>super</code> keyword</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
<span class="hljs-keyword">constructor</span>(name) {
<span class="hljs-keyword">super</span>(name);
<span class="hljs-keyword">this</span>.nickname = name + <span class="hljs-string">'y boy'</span>;
}
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-6-12">
<span class="pos">13-6-12</span>
<div class="slidecontent"><p>Since <strong>React components inherit from <code>React.Component</code></strong>, that means that if we have a constructor in our components we <strong>must always call <code>super</code></strong>.</p>
</div></section>
<section class="slide num numB" data-pos="13-6-13">
<span class="pos">13-6-13</span>
<div class="slidecontent">
<p>And you've <strong>already seen methods</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
<span class="hljs-keyword">constructor</span>() { ... }
bark() {
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.name,<span class="hljs-string">"goes woof!"</span>);
}
}
</code></pre>
<p>Similar to object methods, <strong><code>this</code></strong> (normally) <strong>points to the instance</strong>.</p>
</div></section>
<section class="slide num numC" data-pos="13-6-14">
<span class="pos">13-6-14</span>
<div class="slidecontent">
<p>Finally, as you saw, <strong>properties are normally initialized in the constructor</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
<span class="hljs-keyword">constructor</span>(name) {
<span class="hljs-keyword">this</span>.name = name;
}
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-6-15">
<span class="pos">13-6-15</span>
<div class="slidecontent"><p>...but when we use <strong>TypeScript</strong> - more on that soon - we can also <strong>initialise properties directly on the class declaration</strong>:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Dog {
numberOfLegs = <span class="hljs-number">4</span>;
}
</code></pre>
<p>This is <strong>likely to become a part of JavaScript syntax</strong> too.</p>
</div></section>
<section class="slide" data-pos="13-6-16">
<span class="pos">13-6-16</span>
<div class="slidecontent"><p>So, to <strong>recap</strong>:</p>
<ul>
<li>classes are just a <strong>light syntactic sugar</strong> introduced in ES2015</li>
<li>we normally <strong>don't need them in JavaScript</strong></li>
<li>but they are a <strong>convenient way to bundle related functionality</strong></li>
</ul>
</div></section>
</section>
<section>
<section class="slide sectiontitle">
<div class="slidecontent">
<div class='sectioncount'>Section 7/9</div>
<h3>Decorators</h3>
<p>dewhatnow?</p>
</div>
</section>
<section class="slide" data-pos="13-7-1">
<span class="pos">13-7-1</span>
<div class="slidecontent"><p>The <strong>situation around decorators is rather confusing</strong>;</p>
<ul>
<li>There is a <a href="http://tc39.github.io/proposal-decorators/">proposal</a> to add it as a language feature</li>
<li>There is a slightly different <a href="https://www.typescriptlang.org/docs/handbook/decorators.html">implementation in TypeScript</a></li>
<li>There is the parallel idea in <strong><code>Reflect</code></strong></li>
<li>There is <a href="https://github.com/wycats/javascript-decorators/issues/48">disagreement</a> on whether decorators are a good idea at all</li>
<li>There is (was?) something called <a href="http://blog.thoughtram.io/angular/2015/05/03/the-difference-between-annotations-and-decorators.html">annotations</a> that is sort of the same... yet not</li>
</ul>
</div></section>
<section class="slide" data-pos="13-7-2">
<span class="pos">13-7-2</span>
<div class="slidecontent"><p>Focusing on the <strong>TypeScript implementation</strong> which is the most common, decorators are a way of decorating a class...</p>
<ul>
<li><strong>declaration</strong></li>
<li><strong>property</strong></li>
<li><strong>getter</strong> or <strong>setter</strong></li>
<li><strong>method</strong></li>
<li><strong>method parameter</strong></li>
</ul>
</div></section>
<section class="slide" data-pos="13-7-3">
<span class="pos">13-7-3</span>
<div class="slidecontent"><p>As a simple example, imagine that we have a <strong><code>debounce</code> function</strong> that <strong>throttles other functions</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">debounce</span>(<span class="hljs-params">fn</span>) </span>{
<span class="hljs-comment">// ... create a throttled version of `fn`...</span>
<span class="hljs-keyword">return</span> throttledFn;
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-7-4">
<span class="pos">13-7-4</span>
<div class="slidecontent"><p>And then we have a class with a <strong>method that is very expensive</strong> to call:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">myClass</span> </span>{
myExpensiveMethod: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-comment">// lots of heavy lifting here</span>
}
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-7-5">
<span class="pos">13-7-5</span>
<div class="slidecontent"><p><strong>Without decorators</strong> we would do this:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">myClass</span> </span>{
myExpensiveMethod: debounce(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-comment">// lots of heavy lifting here</span>
})
}
</code></pre>
</div></section>
<section class="slide" data-pos="13-7-6">
<span class="pos">13-7-6</span>
<div class="slidecontent"><p><strong>With decorators</strong>, instead, we use the <code>@</code> syntax:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">myClass</span> </span>{
@debounce
myExpensiveMethod: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-comment">// lots of heavy lifting here</span>
}
}
</code></pre>
<p>The <strong>end result is the same thing</strong>.</p>
</div></section>
<section class="slide" data-pos="13-7-7">
<span class="pos">13-7-7</span>
<div class="slidecontent"><p>We can also have <strong>decorators that take additional arguments</strong>. For instance <code>debounce</code> could accept a <strong>minimum number of milliseconds</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">myClass</span> </span>{
@debounce(<span class="hljs-number">300</span>)
myExpensiveMethod: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-comment">// lots of heavy lifting here</span>
}
}
</code></pre>
<p>In other words, <strong>decorators are just a light syntax sugar</strong>.</p>
</div></section>
<section class="slide" data-pos="13-7-8">
<span class="pos">13-7-8</span>
<div class="slidecontent"><p>If you want to <strong>dig deeper into decorators</strong>, check out...</p>
<ul>
<li>The <a href="https://www.typescriptlang.org/docs/handbook/decorators.html">decorator section</a> of the TypeScript handbook</li>
<li>This <a href="https://github.com/arolson101/typescript-decorators">concise and clear explanation</a> with examples and interactive links</li>
</ul>
</div></section>
</section>
<section>
<section class="slide sectiontitle">
<div class="slidecontent">
<div class='sectioncount'>Section 8/9</div>
<h3>Miscellaneous</h3>
<p>odds and ends</p>
</div>
</section>
<section class="slide list" data-pos="13-8-1">
<span class="pos">13-8-1</span>
<div class="slidecontent">
<p>There's three more things worth mentioning:</p>
<ul>
<li><span>a</span>declaring variables with <strong><code>let</code></strong></li>
<li><span>b</span>declaring variables with <strong><code>const</code></strong></li>
<li><span>c</span><strong>template strings</strong></li>
</ul>
</div></section>
<section class="slide num numA" data-pos="13-8-2">
<span class="pos">13-8-2</span>
<div class="slidecontent">
<p>Variables in JavaScript have <strong>functional scope</strong>.</p>
<p>Even if you declare them inside an <strong>if-block in the middle of a function</strong>, the variable is still <strong>visible throughout the entire function</strong>.</p>
</div></section>
<section class="slide" data-pos="13-8-3">
<span class="pos">13-8-3</span>
<div class="slidecontent"><p>So when you write this...</p>
<pre><code>function myFunc(arg,<span class="hljs-class"><span class="hljs-keyword">lib</span>){</span>
<span class="hljs-keyword">if</span> (arg === <span class="hljs-number">42</span>){
var ret = <span class="hljs-class"><span class="hljs-keyword">lib</span>.<span class="hljs-title">method</span>() + 7;</span>
<span class="hljs-keyword">return</span> ret;
}
/<span class="hljs-regexp">/ do sth else
}</span>
</code></pre></div></section>
<section class="slide" data-pos="13-8-4">
<span class="pos">13-8-4</span>
<div class="slidecontent"><p>...this is what (conceptually) happens:</p>
<pre><code>function myFunc(arg,<span class="hljs-class"><span class="hljs-keyword">lib</span>){</span>
var ret;
<span class="hljs-keyword">if</span> (arg === <span class="hljs-number">42</span>){
ret = <span class="hljs-class"><span class="hljs-keyword">lib</span>.<span class="hljs-title">method</span>() + 7;</span>
<span class="hljs-keyword">return</span> ret;
}
/<span class="hljs-regexp">/ do sth else
}</span>
</code></pre><p>In other words, the <strong>declaration is hoisted to the top</strong>.</p>
</div></section>
<section class="slide" data-pos="13-8-5">
<span class="pos">13-8-5</span>
<div class="slidecontent"><p>This is generally considered a <strong>design mistake</strong>, and can give rise to <strong>weird bugs</strong>.</p>
<p>ES6 therefore introduces <strong><code>let</code> as an alternative to <code>var</code></strong> for declaring variables, and the <strong>only difference</strong> is that <strong><code>let</code> has block scope</strong>.</p>
</div></section>
<section class="slide num numB" data-pos="13-8-6">
<span class="pos">13-8-6</span>
<div class="slidecontent">
<p>In most languages there's a way to <strong>define constants</strong>, meaning a <strong>variable that cannot change</strong>.</p>
<p>This is <strong>missing from JavaScript</strong>.</p>
</div></section>
<section class="slide" data-pos="13-8-7">
<span class="pos">13-8-7</span>
<div class="slidecontent"><p>A common "hack" is to <strong>name constants in all capitals</strong>:</p>
<pre><code>var SOME_CONST = <span class="hljs-number">42</span><span class="hljs-comment">;</span>
</code></pre><p>But this has <strong>no technical significance</strong>, it is just a hint.</p>
</div></section>
<section class="slide" data-pos="13-8-8">
<span class="pos">13-8-8</span>
<div class="slidecontent"><p>ES6 therefore introduces <strong><code>const</code> as another alternative to <code>var</code></strong>, and the <strong>only difference</strong> is that you <strong>cannot reassign the value</strong>.</p>
<pre><code>const answer = <span class="hljs-number">42</span><span class="hljs-comment">;</span>
<span class="hljs-attribute">answer</span> = <span class="hljs-number">43</span><span class="hljs-comment">; // throws an error</span>
</code></pre></div></section>
<section class="slide num numC" data-pos="13-8-9">
<span class="pos">13-8-9</span>
<div class="slidecontent">
<p>Finally, <strong>template strings</strong>!</p>
<pre><code><span class="hljs-keyword">let</span> userTempl = <span class="hljs-string">`
First name: <span class="hljs-subst">${user.fname}</span>
Last name: <span class="hljs-subst">${user.lname}</span>