-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathbasics.tex
767 lines (637 loc) · 23.6 KB
/
basics.tex
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
\chapter{Basic Features}\label{s:basics}
This lesson introduces the core features of JavaScript,
including how to run programs,
the language's basic data types,
arrays and objects,
loops,
conditionals,
functions,
and modules.
All of these concepts should be familiar if you have programmed before.
\section{Hello, World}\label{s:basics-hello-world}
Use your favorite text editor to put the following line in a file called \texttt{hello.js}:
\begin{minted}{js}
console.log('hello, world')
\end{minted}
\texttt{console}\index{console.log|texttt} is a built-in \gref{g:module}{module}
that provides basic printing services
(among other things).
As in many languages,
we use the \gref{g:dotted-notation}{dotted notation} \texttt{X.Y}
to get part \texttt{Y} of thing \texttt{X}---in this case,
to get \texttt{console}'s \texttt{log} function.
\grefdex{g:string}{Character strings}{character string} like \texttt{'hello,\ world'}
can be written with either single quotes or double quotes,
so long as the quotation marks match,
and semi-colons at the ends of statements are now (mostly) optional.
To run a program\index{running JavaScript!from the command line},
type \texttt{node\ program\_name.js} at the command line.
(We will preface shell commands with \texttt{\$} to make them easier to spot.)
\begin{minted}{shell}
$ node src/basics/hello.js
\end{minted}
\begin{minted}{text}
hello, world
\end{minted}
\section{Basic Data Types}\label{s:basics-data-types}
JavaScript has the usual datatypes,\index{datatypes!number}
though unlike C, Python, and many other languages,
there is no separate type for integers:\index{datatypes!integer (lack of)}
it stores all numbers as 64-bit floating-point values,
which is accurate up to about 15 decimal digits.
We can check this using \texttt{typeof},\index{typeof operator@\texttt{typeof} operator}
which returns a string.
(Note: \texttt{typeof} is an operator,
\emph{not} a function:
we apply it to something by typing a space followed by
the name of the thing we'd like to check the type of,
e.g., \texttt{typeof dress} as opposed to \texttt{typeof(dress)}.)
We use it alongside \texttt{const} below,
which itself is helpful when we want to give a name to a
\gref{g:constant}{constant} value:
\begin{minted}{js}
const aNumber = 123.45
console.log('the type of', aNumber, 'is', typeof aNumber)
\end{minted}
\begin{minted}{text}
the type of 123.45 is number
\end{minted}
\begin{minted}{js}
const anInteger = 123
console.log('the type of', anInteger, 'is', typeof anInteger)
\end{minted}
\begin{minted}{text}
the type of 123 is number
\end{minted}
We have already met strings,
which may contain any \gref{g:unicode}{Unicode} character:
\begin{minted}{js}
const aString = 'some text'
console.log('the type of', aString, 'is', typeof aString)
\end{minted}
\begin{minted}{text}
the type of some text is string
\end{minted}
Functions are also a type of data,
a fact whose implications we will explore in \chapref{s:callbacks}:
\begin{minted}{js}
console.log('the type of', console.log, 'is', typeof console.log)
\end{minted}
\begin{minted}{text}
the type of function () { [native code] } is function
\end{minted}
Rather than showing the other basic types one by one,
we will put three values in a list and loop over it:
\begin{minted}{js}
const otherValues = [true, undefined, null]
for (let value of otherValues) {
console.log('the type of', value, 'is', typeof value)
}
\end{minted}
\begin{minted}{text}
the type of true is boolean
the type of undefined is undefined
the type of null is object
\end{minted}
\noindent
As the example above shows, we create an array of values to loop through called \texttt{otherValues}.
We initiate our loop with the word \texttt{for}.\index{for loop@\texttt{for} loop}\index{loop!\texttt{for}}
Within the parentheses,
\texttt{let} creates a variable\index{variable!defining}
called \texttt{value} to iterate over each element within \texttt{otherValues},
and \texttt{value} is the changing array value of \texttt{otherValues}.
Finally, within the curly braces we perform our desired operation on every value.
Note that we use \texttt{let} rather than the older \texttt{var}
and \texttt{of} rather than \texttt{in}:
the latter returns the indexes of the collection (e.g., 0, 1, 2),
which has some traps for the unwary (\appref{s:legacy-iteration}).
Note also that indexing starts from 0 rather than 1,
and that indentation is optional and for readability purposes only.
This may be different from the language that you're used to.
\begin{aside}{Constants versus Variables}
You should make things constants unless they really need to be variables
because it's easier for both people and computers to keep track of things
that are defined once and never change.
\end{aside}
After all this,
the types themselves are somewhat anticlimactic.
JavaScript's \grefdex{g:boolean}{\texttt{boolean}}{Boolean} type\index{datatype!Boolean}
can be either \texttt{true} or \texttt{false},
though we will see below that other things can be treated as Booleans.
\texttt{undefined} means ``hasn't been given a value'',\index{datatype!undefined}
while \texttt{null} means ``has a value, which is nothing''.\index{datatype!null}
\section{Control Flow}\label{s:basics-control-flow}
We have already seen \texttt{for} loops and flat arrays,
so let's have a look at nested arrays and conditionals.
We start with arrays that contain other arrays,\index{nested!arrays}\index{array!nested}
which are usually processed by \grefdex{g:nested-loop}{nested loops}{nested!loops}:\index{loop!nested}
\begin{minted}{js}
const nested = [['northwest', 'northeast'],
['southwest', 'southeast']]
for (let outer of nested) {
for (let inner of outer) {
console.log(inner)
}
}
\end{minted}
\begin{minted}{text}
northwest
northeast
southwest
southeast
\end{minted}
The \gref{g:inner-loop}{inner loop} runs a complete cycle of iterations
for each iteration of the \gref{g:outer-loop}{outer loop}.
Each value assigned to the variable \texttt{outer} is a pair,
so each value assigned to \texttt{inner} is one of the two strings from that pair
(\figref{f:basics-traversal}).
\figpdf{figures/basics-traversal.pdf}{Nested Loop Traversal}{f:basics-traversal}
A JavaScript program can also make choices:
it executes the \gref{g:body-statement}{body} of an \texttt{if} statement
if and only if the \gref{g:condition}{condition} is true.
Each \texttt{if} can have an \texttt{else},
whose body is only executed if the condition \emph{isn't} true:
\begin{minted}{js}
const values = [0, 1, '', 'text', undefined, null, [], [2, 3]]
for (let element of values) {
if (element) {
console.log(element, 'of type', typeof element, 'is truthy')
} else {
console.log(element, 'of type', typeof element, 'is falsy')
}
}
\end{minted}
\begin{minted}{text}
0 of type number is falsy
1 of type number is truthy
of type string is falsy
text of type string is truthy
undefined of type undefined is falsy
null of type object is falsy
of type object is truthy
2,3 of type object is truthy
\end{minted}
This example shows that arrays are \gref{g:heterogeneous}{heterogeneous},
i.e.,
that they can contain values of many different types.
It also shows that JavaScript has some rather odd ideas about the nature of truth.
0 is \gref{g:falsy}{falsy},\index{neologism (horrible)}
while all other numbers are \gref{g:truthy}{truthy};
similarly,
the empty string is falsy and all other strings are truthy.
\texttt{undefined} and \texttt{null} are both falsy,
as most programmers would expect.
But as the last two lines of output show,
an empty array is truthy,
which is different from its treatment in most programming languages.
The argument made by JavaScript's advocates is that an empty array is there,
it just happens to be empty,
but this behavior is still a common cause of bugs.
When testing an array,
check that \texttt{Array.length} is zero.\index{array!length}
(Note that this is a \gref{g:property}{property},
not a \gref{g:method}{method},
i.e.,
it should be treated as a variable,
not called like a function.)
\begin{aside}{Safety Tip}
Always use \texttt{===} (triple equals) and \texttt{!==}
when testing for equality and inequality in JavaScript.\index{equality!forms of}
\texttt{==} and \texttt{!=} do type conversion,
which can produce some ugly surprises (\secref{s:legacy-equality}).
\end{aside}
\section{Formatting Strings}\label{s:basics-formatting}
Rather than printing multiple strings and expressions,
we can \grefdex{g:string-interpolation}{interpolate}{string interpolation}\index{interpolation!string}
values into a back-quoted string.
(We have to use back quotes because this feature was added to JavaScript
long after the language was first created.)
As the example below shows,
the value to be interpolated is put in \texttt{\$\{...\}},
and can be any valid JavaScript expression,
including a function or method call.
\begin{minted}{js}
for (let color of ['red', 'green', 'blue']) {
const message = `color is ${color}`
console.log(message, `and capitalized is ${color.toUpperCase()}`)
}
\end{minted}
\begin{minted}{text}
color is red and capitalized is RED
color is green and capitalized is GREEN
color is blue and capitalized is BLUE
\end{minted}
\noindent
This allows us to succinctly add variables to a string instead of:
\begin{minted}{js}
const message = "color is" + color + "and capitalized is " + color.toUpperCase()
\end{minted}
\section{Objects}\label{s:basics-objects}
An \gref{g:object}{object} in JavaScript is a collection of key-value pairs,
and is equivalent in simple cases to what Python would call a dictionary.
It's common to visualize an object as a two-column table
with the keys in one column and the values in another (\figref{f:basics-object-table}).
The keys must be strings;\index{object!keys}
the values can be anything.\index{object!values}
We can create an object by putting key-value pairs in curly brackets;
there must be a colon between the key and the value,
and pairs must be separated by commas like the elements of arrays:
\figpdf{figures/basics-object-table.pdf}{Objects in Memory}{f:basics-object-table}
\begin{minted}{js}
const creature = {
'order': 'Primates',
'family': 'Callitrichidae',
'genus': 'Callithrix',
'species': 'Jacchus'
}
console.log(`creature is ${creature}`)
console.log(`creature.genus is ${creature.genus}`)
for (let key in creature) {
console.log(`creature[${key}] is ${creature[key]}`)
}
\end{minted}
\begin{minted}{text}
creature is [object Object]
creature.genus is Callithrix
creature[order] is Primates
creature[family] is Callitrichidae
creature[genus] is Callithrix
creature[species] is Jacchus
\end{minted}
The type of an object is always \texttt{object}.
We can get the value associated with a key using \texttt{object[key]},
but if the key has a simple name,
we can use \texttt{object.key} instead.
Note that the square bracket form can be used with variables for keys,
but the dotted notation cannot:
i.e.,
\texttt{creature.genus} is the same as \texttt{creature['genus']},
but the assignment \texttt{g\ =\ 'genus'} followed by \texttt{creature.g} does not work.
Because string keys are so common,
and because programmers use simple names so often,
JavaScript allows us to create objects without quoting the names of the keys:
\begin{minted}{js}
const creature = {
order: 'Primates',
family: 'Callitrichidae',
genus: 'Callithrix',
species: 'Jacchus'
}
\end{minted}
\texttt{[object\ Object]} is not particularly useful output when we want to see what an object contains.
To get a more helpful string representation,
use \texttt{JSON.stringify(object)}:\index{object!string representation}
\begin{minted}{js}
console.log(JSON.stringify(creature))
\end{minted}
\begin{minted}{text}
{"order":"Primates","family":"Callitrichidae",
"genus":"Callithrix","species":"Jacchus"}
\end{minted}
\noindent
Here,
``JSON'' stands for ``JavaScript Object Notation'';\index{JSON}
we will learn more about it in \chapref{s:dataman}.
\section{Functions}\label{s:basics-functions}
Functions make it possible for mere mortals to understand programs
by allowing us to think about them one piece at a time.
Here is a function that finds the lowest and highest values in an array:
\begin{minted}{js}
function limits (values) {
if (!values.length) {
return [undefined, undefined]
}
let low = values[0]
let high = values[0]
for (let v of values) {
if (v < low) low = v
if (v > high) high = v
}
return [low, high]
}
\end{minted}
Its definition consists of the keyword \texttt{function},\index{function!classic}
its name,
a parenthesized list of \grefdex{g:parameter}{parameters}{parameter}\index{function!parameter}
(which might be empty),
and its body.
The body of the function begins with a test of the thing,
referred to inside the function as \texttt{values},
provided as an \gref{g:argument}{argument} to the function.
If \texttt{values} has no length---i.e.,
it does not consist of multiple entries---the function returns \texttt{[undefined,undefined]}.
(We will address the rationale behind this behavior in the exercises.)
\begin{minted}{js}
if (!values.length) {
return [undefined, undefined]
}
\end{minted}
\noindent
If that initial check finds that \texttt{values} does have a length---i.e.,
\texttt{!values.length} returns \texttt{false}---the rest of the function is run.
This involves first initializing two variables,
\texttt{low} and \texttt{high},
with their values set as equal to the first item in \texttt{values}.
\begin{minted}{js}
let low = values[0]
let high = values[0]
\end{minted}
In the next stage of the function,
all of the values are iterated over and \texttt{low} and \texttt{high} are
assigned a new value,
equal to that of the next item,
if that value is lower than \texttt{low} or higher than \texttt{high} respectively.
\begin{minted}{js}
for (let v of values) {
if (v < low) low = v
if (v > high) high = v
}
\end{minted}
Once all of the items in \texttt{values} have been examined,
the values of \texttt{low} and \texttt{high} are the minimum and maximum of \texttt{values}.
These are returned as a pair inside an array.
\begin{minted}{js}
return [low, high]
\end{minted}
\noindent
Note that we can use \texttt{return} to explicitly return a value at any time;\index{function!return}\index{return statement}
if nothing is returned,
the function's result is \texttt{undefined}.\index{function!default value}
One oddity of JavaScript is that almost anything can be compared to almost anything else.
Here are a few tests that demonstrate this:
\begin{minted}{js}
const allTests = [
[],
[9],
[3, 30, 300],
['apple', 'Grapefruit', 'banana'],
[3, 'apple', ['sub-array']]
]
for (let test of allTests) {
console.log(`limits of ${test} are ${limits(test)}`)
}
\end{minted}
\begin{minted}{text}
limits of are ,
limits of 9 are 9,9
limits of 3,30,300 are 3,300
limits of apple,Grapefruit,banana are Grapefruit,banana
limits of 3,apple,sub-array are 3,3
\end{minted}
Programmers generally don't write functions this way any longer,
since it interacts in odd ways with other features of the language;
\secref{s:legacy-prototypes} explains why and how in more detail.
Instead,
most programmers now write \grefdex{g:fat-arrow}{fat arrow functions}{fat arrow function}\index{function!fat arrow}
consisting of a parameter list,
the \texttt{=\textgreater{}} symbol,
and a body.
Fat arrow functions don't have names,
so the function must be assigned that to a constant or variable for later use:
\begin{minted}{js}
const limits = (values) => {
if (!values.length) {
return [undefined, undefined]
}
let low = values[0]
let high = values[0]
for (let v of values) {
if (v < low) low = v
if (v > high) high = v
}
return [low, high]
}
\end{minted}
No matter how functions are defined,
each one is a \grefdex{g:scope}{scope}{scope (of variable)},\index{variable scope}
which means its parameters and any variables created inside it
are \grefdex{g:local-variable}{local}{local variable}\index{variable!local} to the function.
We will discuss scope in more detail in \chapref{s:callbacks}.
\begin{aside}{Stuck in the Past}
Why did JavaScript introduce another syntax
rather than fixing the behavior of those defined with \texttt{function}?
The twin answers are that changes would break legacy programs that rely on the old behavior,
and that the language's developers wanted to make it really easy to define little functions.
Here and elsewhere,
we will see how a language's history and use shape its evolution.
\end{aside}
\section{Modules}\label{s:basics-modules}
As our programs grow larger,
we will want to put code in multiple files.
The unavoidable bad news is that JavaScript has several module systems:
Node still uses one called CommonJS,\index{CommonJS module system}\index{module system!CommonJS}
but is converting to the modern standard called ES6,\index{ES6 module system}\index{module system!ES6}
so what we use on the command line is different from what we use in the browser (for now).
\begin{aside}{Ee Ess}
JavaScript's official name is ECMAScript,\index{ECMAScript}
though only people who use the word ``datum'' in everyday conversation ever call it that.
Successive versions of the language are therefore known as ES5, ES6, and so on,
except when they're referred to as (for example) ES2018.
\end{aside}
Since we're going to build command-line programs before doing anything in the browser,
we will introduce Node's module system first (\figref{f:basics-require}).
We start by putting this code in a file called \texttt{utilities.js}:
\begin{minted}{js}
DEFAULT_BOUND = 3
const clip = (values, bound = DEFAULT_BOUND) => {
let result = []
for (let v of values) {
if (v <= bound) {
result.push(v)
}
}
return result
}
module.exports = {
clip: clip
}
\end{minted}
The function definition is straightforward;
as you may have guessed, \texttt{bound\ =\ DEFAULT\_BOUND} sets a default value for that parameter
so that \texttt{clip} can be called with just an array.
You may also have guessed that \texttt{Array.push} appends a value to the end of an array;
if you didn't,
well,
now you know.
What's more important is assigning an object to \texttt{module.exports}.\index{module!exports}
Only those things named in this object are visible to the outside world,
so \texttt{DEFAULT\_BOUND} won't be.
Remember,
keys that are simple names don't have to be quoted,
so \texttt{clip:\ clip} means ``associate a reference to the function \texttt{clip} with the string key \texttt{"clip"}.
To use our newly-defined module we must \texttt{require} it.\index{module!imports}\index{module!\texttt{require}}
For example,
we can put this in \texttt{application.js}:
\begin{minted}{js}
const utilities = require('./utilities')
const data = [-1, 5, 3, 0, 10]
console.log(`clip(${data}) -> ${utilities.clip(data)}`)
console.log(`clip(${data}, 5) -> ${utilities.clip(data, 5)}`)
\end{minted}
\begin{minted}{text}
clip(-1,5,3,0,10) -> -1,3,0
clip(-1,5,3,0,10, 5) -> -1,5,3,0
\end{minted}
\noindent
\texttt{require} returns the object that was assigned to \texttt{module.exports},
so if we have assigned its result to a variable called \texttt{utilities},
we must then call our function as \texttt{utilities.clip}.
We use a relative path starting with \texttt{./} or \texttt{../} to import local files;
paths that start with names are taken from installed Node libraries.
\figpdf{figures/basics-require.pdf}{How Require Works}{f:basics-require}
\section{Exercises}\label{s:basics-exercises}
\exercise{Typeof}
What kind of thing is \texttt{typeof}?
Is it an expression?
A function?
Something else?
(You might notice that \texttt{typeof\ typeof} is syntactically invalid.
In such circumstances,
an Internet search engine is your friend,
as is the \hreffoot{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference}{Mozilla Developer Network}\index{Mozilla Developer Network} JavaScript reference.)
\exercise{Fill in the Blanks}
Answer these questions about the program below:
\begin{enumerate}
\item
What does \texttt{Array.push} do?
\item
How does a \texttt{while} loop work?
\item
What does \texttt{+=} do?
\item
What does \texttt{Array.reverse} do, and what does it return?
\end{enumerate}
\begin{minted}{js}
let current = 0
let table = []
while (current < 5) {
const entry = `square of ${current} is ${current * current}`
table.push(entry)
current += 1
}
table.reverse()
for (let line of table) {
console.log(line)
}
\end{minted}
\begin{minted}{text}
square of 4 is 16
square of 3 is 9
square of 2 is 4
square of 1 is 1
square of 0 is 0
\end{minted}
\exercise{What Is Truth?}
Write a function called \texttt{isTruthy} that returns \texttt{true} for everything that JavaScript considers truthy,
and \texttt{false} for everything it considers \texttt{falsy} \emph{except} empty arrays:
\texttt{isTruthy} should return \texttt{false} for those.
\exercise{The Shape of Things to Come}
We wrote the example function, \texttt{limits},
above to return \texttt{[undefined,undefined]} if a variable
with no length is fed into it.
What is the advantage of doing this as opposed to
returning \texttt{undefined} only?
\exercise{Combining Different Types}
What does \grefdex{g:nan}{\texttt{NaN}}{Not a Number} represent?\index{NaN@\texttt{NaN} (Not a Number)}
What output would you expect from the code below?
Try running it and see whether the results match your expectations.
What are the implications of this behavior when working with real-world data?
\begin{minted}{js}
const first = [3, 7, 8, 9, 1]
console.log(`aggregating ${first}`)
let total = 0
for (let d of first) {
total += d
}
console.log(total)
const second = [0, 3, -1, NaN, 8]
console.log(`aggregating ${second}`)
total = 0
for (let d of second) {
total += d
}
console.log(total)
\end{minted}
\exercise{What Does This Do?}
Explain what is happening in the assignment statement that creates the constant \texttt{creature}.
\begin{minted}{js}
const genus = 'Callithrix'
const species = 'Jacchus'
const creature = {genus, species}
console.log(creature)
\end{minted}
\begin{minted}{text}
{ genus: 'Callithrix', species: 'Jacchus' }
\end{minted}
\exercise{Destructuring Assignment}
When this short program runs:
\begin{minted}{js}
const creature = {
genus: 'Callithrix',
species: 'Jacchus'
}
const {genus, species} = creature
console.log(`genus is ${genus}`)
console.log(`species is ${species}`)
\end{minted}
\noindent
it produces the output:
\begin{minted}{text}
genus is Callithrix
species is Jacchus
\end{minted}
\noindent
but when this program runs:
\begin{minted}{js}
const creature = {
first: 'Callithrix',
second: 'Jacchus'
}
const {genus, species} = creature
console.log(`genus is ${genus}`)
console.log(`species is ${species}`)
\end{minted}
\noindent
it produces:
\begin{minted}{text}
genus is undefined
species is undefined
\end{minted}
\begin{enumerate}
\item
What is the difference between these two programs?
\item
How does \gref{g:destructuring}{destructuring assignment} work in general?
\item
How can we use this technique to rewrite the \texttt{require} statement in \texttt{src/basics/application.js}
so that \texttt{clip} can be called directly as \texttt{clip(...)} rather than as \texttt{utilities.clip(...)}?
\end{enumerate}
\exercise{Return To Me, For My Heart Wants You Only}
What output would you see in the console if you ran this code?
\begin{minted}{js}
const verbose_sum = (first, second) => {
console.log(`Going to add ${first} to ${second}`)
let total = first + second
return total
console.log(`Finished summing`)
}
var result = verbose_sum(3, 6)
console.log(result)
\end{minted}
\begin{enumerate}
\item
\texttt{Going\ to\ add\ \$\{first\}\ to\ \$\{second\}}\\
\texttt{9}
\item
\texttt{Going\ to\ add\ 3\ to\ 6}\\
\texttt{9}\\
\texttt{Finished\ summing}
\item
\texttt{Going\ to\ add\ 3\ to\ 6}\\
\texttt{9}
\item
\texttt{Going\ to\ add\ 3\ to\ 6}\\
\texttt{36}
\end{enumerate}
\section*{Key Points}
\input{keypoints/basics}