aboutsummaryrefslogtreecommitdiff
path: root/files/vi/web/javascript/a_re-introduction_to_javascript/index.html
blob: 531fb96fc0c2d4a39e188712838b105ef052ce4a (plain)
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
---
title: A re-introduction to JavaScript (JS tutorial)
slug: Web/JavaScript/A_re-introduction_to_JavaScript
translation_of: Web/JavaScript/A_re-introduction_to_JavaScript
---
<div>{{jsSidebar}}</div>

<p>Tại sao lại là giới thiệu lại? Đó là vì <a href="/en-US/docs/Glossary/JavaScript">JavaScript</a> được coi là một trong những ngôn ngữ hay bị hiểu lầm nhất thế giới. Nó thường chỉ được coi như một món đồ chơi, nhưng bên dưới sự đơn giản đó lại ẩn chứa rất nhiều sức mạnh. JavaScript hiện được dùng bởi rất rất nhiều ứng dụng mạnh mẽ, và một sự hiểu biết sâu sắc về công nghệ này giờ là một trong những kỹ năng quan trọng của bất kỳ lập trình viên web hay ứng dụng di động nào.</p>

<p>Biết một chút về lịch sử của ngôn ngữ này là rất hữu dụng. JavaScript được tạo ra năm 1995 bởi Brendan Eich khi ông đang là một kỹ sư tại Netscape. JavaScript lần đầu được phát hàng cùng với Netscape 2 đầu năm 1996. Ban đầu nó dự định được gọi là LiveScript, nhưng sau đó đổi lại trong một quyết định marketing sai lầm khi cố gắng nhấn mạnh sự phổ biến của Java, ngôn ngữ lập trình được phát triển bởi Sun Microsystems - dù rằng chúng có rất ít điểm chung. Đây chính là cội rễ của mọi sự hiểu lầm kể từ đó.</p>

<p>Vài tháng sau đó, Microsoft đã phát hành JScript cùng với Internet Explorer 3. Đó cũng là một trong những bản tương thích JavaScript nhiều nhất. Vài tháng sau đó, Netscape gửi JavaScript lên cho <a class="external" href="http://www.ecma-international.org/">Ecma International</a>, một tổ chức tiêu chuẩn của châu Âu, và kết quả là năm đó phiên bản đầu tiên của chuẩn <a href="/en-US/docs/Glossary/ECMAScript">ECMAScript</a> được đưa ra. Chuẩn này sau đó tiếp tục được cập nhật đáng kể với phiên bản <a class="external" href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript edition 3</a> vào năm 1999, và giữ ổn định kể từ đó. Phiên bản thứ 4 bị hủy bỏ do một số khác biệt về chính sách liên quan đến sự phức tạp của ngôn ngữ. Nhiều phần của phiên bản 4 sau đó trở thành nền tảng cho ECMAScript edition 5, được phát hành vào tháng 12 năm 2009, và cho phiên bản 6 của chuẩn này, phát hành năm 2015.</p>

<div class="note">
<p>Trong tài liệu này chúng ta sẽ nói về ECMAScript với tên "JavaScript".</p>
</div>

<p>Không như hầu hết các ngôn ngữ lập trình, JavaScript không có khái niệm đầu vào hay đầu ra (input/output). Nó được thiết kế để chạy như một ngôn ngữ kịch bản và thực thi trong một môi trường được quản lý (host environment), JavaScript phụ thuộc vào môi trường đang chạy để cung cấp các kỹ thuật khác nhau cho việc giao tiếp với thế giới bên ngoài. Môi trường thực thi phổ biến nhất là trình duyệt, nhưng trình thông dịch JavaScript còn có thể được tìm thấy từ một danh sách khổng lồ khác: Adobe Acrobat, Adobe Photoshop, SVG images, Yahoo's Widget engine, các môi trường thực thi phía server như <a href="http://nodejs.org/">Node.js</a>, các cơ sở dữ liệu NoSQL như phần mềm mã nguồn mở <a href="http://couchdb.apache.org/">Apache CouchDB</a>, các máy tính nhúng, các môi trường desktop như <a href="http://www.gnome.org/">GNOME</a> (một trong những giao diện phổ biến nhất cho GNU/Linux operating systems), và nhiều nơi khác.</p>

<h2 id="Overview">Overview</h2>

<p>JavaScript is a multi-paradigm, dynamic language with types and operators, standard built-in objects, and methods. Its syntax is based on the Java and C languages — many structures from those languages apply to JavaScript as well. JavaScript supports object-oriented programming with object prototypes, instead of classes (see more about <a href="/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain" title="prototypical inheritance">prototypical inheritance</a> and ES2015 <a href="/en-US/docs/Web/JavaScript/Reference/Classes">classes</a>). JavaScript also supports functional programming — because they are objects, functions may be stored in variables and passed around like any other object.</p>

<p>Let's start off by looking at the building blocks of any language: the types. JavaScript programs manipulate values, and those values all belong to a type. JavaScript's types are:</p>

<ul>
 <li>{{jsxref("Number")}}</li>
 <li>{{jsxref("String")}}</li>
 <li>{{jsxref("Boolean")}}</li>
 <li>{{jsxref("Function")}}</li>
 <li>{{jsxref("Object")}}</li>
 <li>{{jsxref("Symbol")}} (new in ES2015)</li>
</ul>

<p>... oh, and {{jsxref("undefined")}} and {{jsxref("null")}}, which are ... slightly odd. And {{jsxref("Array")}}, which is a special kind of object. And {{jsxref("Date")}} and {{jsxref("RegExp")}}, which are objects that you get for free. And to be technically accurate, functions are just a special type of object. So the type diagram looks more like this:</p>

<ul>
 <li>{{jsxref("Number")}}</li>
 <li>{{jsxref("String")}}</li>
 <li>{{jsxref("Boolean")}}</li>
 <li>{{jsxref("Symbol")}} (new in ES2015)</li>
 <li>{{jsxref("Object")}}
  <ul>
   <li>{{jsxref("Function")}}</li>
   <li>{{jsxref("Array")}}</li>
   <li>{{jsxref("Date")}}</li>
   <li>{{jsxref("RegExp")}}</li>
  </ul>
 </li>
 <li>{{jsxref("null")}}</li>
 <li>{{jsxref("undefined")}}</li>
</ul>

<p>And there are some built-in {{jsxref("Error")}} types as well. Things are a lot easier if we stick with the first diagram, however, so we'll discuss the types listed there for now.</p>

<h2 id="Numbers">Numbers</h2>

<p>Numbers in JavaScript are "double-precision 64-bit format IEEE 754 values", according to the spec. This has some interesting consequences. There's no such thing as an integer in JavaScript, so you have to be a little careful with your arithmetic if you're used to math in C or Java.</p>

<p>Also, watch out for stuff like:</p>

<pre class="brush: js notranslate">0.1 + 0.2 == 0.30000000000000004;
</pre>

<p>In practice, integer values are treated as 32-bit ints, and some implementations even store it that way until they are asked to perform an instruction that's valid on a Number but not on a 32-bit integer. This can be important for bit-wise operations.</p>

<p>The standard <a href="/en-US/docs/Web/JavaScript/Reference/Operators#Arithmetic_operators">arithmetic operators</a> are supported, including addition, subtraction, modulus (or remainder) arithmetic, and so forth. There's also a built-in object that we did not mention earlier called {{jsxref("Math")}} that provides advanced mathematical functions and constants:</p>

<pre class="brush: js notranslate">Math.sin(3.5);
var circumference = 2 * Math.PI * r;
</pre>

<p>You can convert a string to an integer using the built-in {{jsxref("Global_Objects/parseInt", "parseInt()")}} function. This takes the base for the conversion as an optional second argument, which you should always provide:</p>

<pre class="brush: js notranslate">parseInt('123', 10); // 123
parseInt('010', 10); // 10
</pre>

<p>In older browsers, strings beginning with a "0" are assumed to be in octal (radix 8), but this hasn't been the case since 2013 or so. Unless you're certain of your string format, you can get surprising results on those older browsers:</p>

<pre class="brush: js notranslate">parseInt('010');  //  8
parseInt('0x10'); // 16
</pre>

<p>Here, we see the {{jsxref("Global_Objects/parseInt", "parseInt()")}} function treat the first string as octal due to the leading 0, and the second string as hexadecimal due to the leading "0x". The <em>hexadecimal notation is still in place</em>; only octal has been removed.</p>

<p>If you want to convert a binary number to an integer, just change the base:</p>

<pre class="brush: js notranslate">parseInt('11', 2); // 3
</pre>

<p>Similarly, you can parse floating point numbers using the built-in {{jsxref("Global_Objects/parseFloat", "parseFloat()")}} function. Unlike its {{jsxref("Global_Objects/parseInt", "parseInt()")}} cousin, <code>parseFloat()</code> always uses base 10.</p>

<p>You can also use the unary <code>+</code> operator to convert values to numbers:</p>

<pre class="brush: js notranslate">+ '42';   // 42
+ '010';  // 10
+ '0x10'; // 16
</pre>

<p>A special value called {{jsxref("NaN")}} (short for "Not a Number") is returned if the string is non-numeric:</p>

<pre class="brush: js notranslate">parseInt('hello', 10); // NaN
</pre>

<p><code>NaN</code> is toxic: if you provide it as an operand to any mathematical operation, the result will also be <code>NaN</code>:</p>

<pre class="brush: js notranslate">NaN + 5; // NaN
</pre>

<p>You can test for <code>NaN</code> using the built-in {{jsxref("Global_Objects/isNaN", "isNaN()")}} function:</p>

<pre class="brush: js notranslate">isNaN(NaN); // true
</pre>

<p>JavaScript also has the special values {{jsxref("Infinity")}} and <code>-Infinity</code>:</p>

<pre class="brush: js notranslate"> 1 / 0; //  Infinity
-1 / 0; // -Infinity
</pre>

<p>You can test for <code>Infinity</code>, <code>-Infinity</code> and <code>NaN</code> values using the built-in {{jsxref("Global_Objects/isFinite", "isFinite()")}} function:</p>

<pre class="brush: js notranslate">isFinite(1 / 0); // false
isFinite(-Infinity); // false
isFinite(NaN); // false
</pre>

<div class="note">The {{jsxref("Global_Objects/parseInt", "parseInt()")}} and {{jsxref("Global_Objects/parseFloat", "parseFloat()")}} functions parse a string until they reach a character that isn't valid for the specified number format, then return the number parsed up to that point. However the "+" operator simply converts the string to <code>NaN</code> if there is an invalid character contained within it. Just try parsing the string "10.2abc" with each method by yourself in the console and you'll understand the differences better.</div>

<h2 id="Strings">Strings</h2>

<p>Strings in JavaScript are sequences of <a href="/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals#Unicode">Unicode characters</a>. This should be welcome news to anyone who has had to deal with internationalization. More accurately, they are sequences of UTF-16 code units; each code unit is represented by a 16-bit number. Each Unicode character is represented by either 1 or 2 code units.</p>

<p>If you want to represent a single character, you just use a string consisting of that single character.</p>

<p>To find the length of a string (in code units), access its <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length">length</a></code> property:</p>

<pre class="brush: js notranslate">'hello'.length; // 5
</pre>

<p>There's our first brush with JavaScript objects! Did we mention that you can use strings like {{jsxref("Object", "objects", "", 1)}} too? They have {{jsxref("String", "methods", "#Methods", 1)}} as well that allow you to manipulate the string and access information about the string:</p>

<pre class="brush: js notranslate">'hello'.charAt(0); // "h"
'hello, world'.replace('world', 'mars'); // "hello, mars"
'hello'.toUpperCase(); // "HELLO"
</pre>

<h2 id="Other_types">Other types</h2>

<p>JavaScript distinguishes between {{jsxref("null")}}, which is a value that indicates a deliberate non-value (and is only accessible through the <code>null</code> keyword), and {{jsxref("undefined")}}, which is a value of type <code>undefined</code> that indicates an uninitialized variable — that is, a value hasn't even been assigned yet. We'll talk about variables later, but in JavaScript it is possible to declare a variable without assigning a value to it. If you do this, the variable's type is <code>undefined</code>. <code>undefined</code> is actually a constant.</p>

<p>JavaScript has a boolean type, with possible values <code>true</code> and <code>false</code> (both of which are keywords.) Any value can be converted to a boolean according to the following rules:</p>

<ol>
 <li><code>false</code>, <code>0</code>, empty strings (<code>""</code>), <code>NaN</code>, <code>null</code>, and <code>undefined</code> all become <code>false.</code></li>
 <li>All other values become <code>true.</code></li>
</ol>

<p>You can perform this conversion explicitly using the <code>Boolean()</code> function:</p>

<pre class="brush: js notranslate">Boolean('');  // false
Boolean(234); // true
</pre>

<p>However, this is rarely necessary, as JavaScript will silently perform this conversion when it expects a boolean, such as in an <code>if</code> statement (see below). For this reason, we sometimes speak simply of "true values" and "false values," meaning values that become <code>true</code> and <code>false</code>, respectively, when converted to booleans. Alternatively, such values can be called "truthy" and "falsy", respectively.</p>

<p>Boolean operations such as <code>&amp;&amp;</code> (logical <em>and</em>), <code>||</code> (logical <em>or</em>), and <code>!</code> (logical <em>not</em>) are supported; see below.</p>

<h2 id="Variables">Variables</h2>

<p>New variables in JavaScript are declared using one of three keywords: <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/let">let</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/const">const</a></code>, or <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/var" title="/en/JavaScript/Reference/Statements/var">var</a></code>.<br>
 <br>
 <strong><code>let</code> </strong>allows you to declare block-level variables. The declared variable is available from the <em>block</em> it is enclosed in.</p>

<pre class="brush: js notranslate">let a;
let name = 'Simon';
</pre>

<p>The following is an example of scope with a variable declared with <code><strong>let</strong></code>:</p>

<pre class="brush: js notranslate">// myLetVariable is *not* visible out here

for (let myLetVariable = 0; myLetVariable &lt; 5; myLetVariable++) {
  // myLetVariable is only visible in here
}

// myLetVariable is *not* visible out here

</pre>

<p><code><strong>const</strong></code> allows you to declare variables whose values are never intended to change. The variable is available from the <em>block</em> it is declared in.</p>

<pre class="brush: js notranslate">const Pi = 3.14; // variable Pi is set
Pi = 1; // will throw an error because you cannot change a constant variable.</pre>

<p><br>
 <code><strong>var</strong></code> is the most common declarative keyword. It does not have the restrictions that the other two keywords have. This is because it was traditionally the only way to declare a variable in JavaScript. A variable declared with the <strong><code>var</code> </strong>keyword is available from the <em>function</em> it is declared in.</p>

<pre class="brush: js notranslate">var a;
var name = 'Simon';</pre>

<p>An example of scope with a variable declared with <strong><code>var</code>:</strong></p>

<pre class="brush: js notranslate">// myVarVariable *is* visible out here

for (var myVarVariable = 0; myVarVariable &lt; 5; myVarVariable++) {
  // myVarVariable is visible to the whole function
}

// myVarVariable *is* visible out here
</pre>

<p>If you declare a variable without assigning any value to it, its type is <code>undefined</code>.</p>

<p>An important difference between JavaScript and other languages like Java is that in JavaScript, blocks do not have scope; only functions have a scope. So if a variable is defined using <code>var</code> in a compound statement (for example inside an <code>if</code> control structure), it will be visible to the entire function. However, starting with ECMAScript 2015, <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/let">let</a></code> and <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/const">const</a></code> declarations allow you to create block-scoped variables.</p>

<h2 id="Operators">Operators</h2>

<p>JavaScript's numeric operators are <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code> and <code>%</code> which is the remainder operator (<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder_%28%29">which is the same as modulo</a>.) Values are assigned using <code>=</code>, and there are also compound assignment statements such as <code>+=</code> and <code>-=</code>. These extend out to <code>x = x <em>operator</em> y</code>.</p>

<pre class="brush: js notranslate">x += 5;
x = x + 5;
</pre>

<p>You can use <code>++</code> and <code>--</code> to increment and decrement respectively. These can be used as a prefix or postfix operators.</p>

<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Addition" title="/en/JavaScript/Reference/Operators/String_Operators"><code>+</code> operator</a> also does string concatenation:</p>

<pre class="brush: js notranslate">'hello' + ' world'; // "hello world"
</pre>

<p>If you add a string to a number (or other value) everything is converted into a string first. This might trip you up:</p>

<pre class="brush: js notranslate">'3' + 4 + 5;  // "345"
 3 + 4 + '5'; // "75"
</pre>

<p>Adding an empty string to something is a useful way of converting it to a string itself.</p>

<p><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en/JavaScript/Reference/Operators/Comparison_Operators">Comparisons</a> in JavaScript can be made using <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code> and <code>&gt;=</code>. These work for both strings and numbers. Equality is a little less straightforward. The double-equals operator performs type coercion if you give it different types, with sometimes interesting results:</p>

<pre class="brush: js notranslate">123 == '123'; // true
1 == true; // true
</pre>

<p>To avoid type coercion, use the triple-equals operator:</p>

<pre class="brush: js notranslate">123 === '123'; // false
1 === true;    // false
</pre>

<p>There are also <code>!=</code> and <code>!==</code> operators.</p>

<p>JavaScript also has <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="/en/JavaScript/Reference/Operators/Bitwise_Operators">bitwise operations</a>. If you want to use them, they're there.</p>

<h2 id="Control_structures">Control structures</h2>

<p>JavaScript has a similar set of control structures to other languages in the C family. Conditional statements are supported by <code>if</code> and <code>else</code>; you can chain them together if you like:</p>

<pre class="brush: js notranslate">var name = 'kittens';
if (name == 'puppies') {
  name += ' woof';
} else if (name == 'kittens') {
  name += ' meow';
} else {
  name += '!';
}
name == 'kittens meow';
</pre>

<p>JavaScript has <code>while</code> loops and <code>do-while</code> loops. The first is good for basic looping; the second for loops where you wish to ensure that the body of the loop is executed at least once:</p>

<pre class="brush: js notranslate">while (true) {
  // an infinite loop!
}

var input;
do {
  input = get_input();
} while (inputIsNotValid(input));
</pre>

<p>JavaScript's <a href="/en-US/docs/Web/JavaScript/Reference/Statements/for"><code>for</code> loop</a> is the same as that in C and Java: it lets you provide the control information for your loop on a single line.</p>

<pre class="brush: js notranslate">for (var i = 0; i &lt; 5; i++) {
  // Will execute 5 times
}
</pre>

<p>JavaScript also contains two other prominent for loops: <a href="/en-US/docs/Web/JavaScript/Reference/Statements/for...of"><code>for</code>...<code>of</code></a></p>

<pre class="brush: js notranslate">for (let value of array) {
  // do something with value
}
</pre>

<p>and <a href="/en-US/docs/Web/JavaScript/Reference/Statements/for...in"><code>for</code>...<code>in</code></a>:</p>

<pre class="brush: js notranslate">for (let property in object) {
  // do something with object property
}
</pre>

<p>The <code>&amp;&amp;</code> and <code>||</code> operators use short-circuit logic, which means whether they will execute their second operand is dependent on the first. This is useful for checking for null objects before accessing their attributes:</p>

<pre class="brush: js notranslate">var name = o &amp;&amp; o.getName();
</pre>

<p>Or for caching values (when falsy values are invalid):</p>

<pre class="brush: js notranslate">var name = cachedName || (cachedName = getName());
</pre>

<p>JavaScript has a ternary operator for conditional expressions:</p>

<pre class="brush: js notranslate">var allowed = (age &gt; 18) ? 'yes' : 'no';
</pre>

<p>The <code>switch</code> statement can be used for multiple branches based on a number or string:</p>

<pre class="brush: js notranslate">switch (action) {
  case 'draw':
    drawIt();
    break;
  case 'eat':
    eatIt();
    break;
  default:
    doNothing();
}
</pre>

<p>If you don't add a <code>break</code> statement, execution will "fall through" to the next level. This is very rarely what you want — in fact it's worth specifically labeling deliberate fallthrough with a comment if you really meant it to aid debugging:</p>

<pre class="brush: js notranslate">switch (a) {
  case 1: // fallthrough
  case 2:
    eatIt();
    break;
  default:
    doNothing();
}
</pre>

<p>The default clause is optional. You can have expressions in both the switch part and the cases if you like; comparisons take place between the two using the <code>===</code> operator:</p>

<pre class="brush: js notranslate">switch (1 + 3) {
  case 2 + 2:
    yay();
    break;
  default:
    neverhappens();
}
</pre>

<h2 id="Objects">Objects</h2>

<p>JavaScript objects can be thought of as simple collections of name-value pairs. As such, they are similar to:</p>

<ul>
 <li>Dictionaries in Python.</li>
 <li>Hashes in Perl and Ruby.</li>
 <li>Hash tables in C and C++.</li>
 <li>HashMaps in Java.</li>
 <li>Associative arrays in PHP.</li>
</ul>

<p>The fact that this data structure is so widely used is a testament to its versatility. Since everything (bare core types) in JavaScript is an object, any JavaScript program naturally involves a great deal of hash table lookups. It's a good thing they're so fast!</p>

<p>The "name" part is a JavaScript string, while the value can be any JavaScript value — including more objects. This allows you to build data structures of arbitrary complexity.</p>

<p>There are two basic ways to create an empty object:</p>

<pre class="brush: js notranslate">var obj = new Object();
</pre>

<p>And:</p>

<pre class="brush: js notranslate">var obj = {};
</pre>

<p>These are semantically equivalent; the second is called object literal syntax and is more convenient. This syntax is also the core of JSON format and should be preferred at all times.</p>

<p>Object literal syntax can be used to initialize an object in its entirety:</p>

<pre class="brush: js notranslate">var obj = {
  name: 'Carrot',
  for: 'Max', // 'for' is a reserved word, use '_for' instead.
  details: {
    color: 'orange',
    size: 12
  }
};
</pre>

<p>Attribute access can be chained together:</p>

<pre class="brush: js notranslate">obj.details.color; // orange
obj['details']['size']; // 12
</pre>

<p>The following example creates an object prototype(<code>Person</code>) and an instance of that prototype(<code>you</code>).</p>

<pre class="brush: js notranslate">function Person(name, age) {
  this.name = name;
  this.age = age;
}

// Define an object
var you = new Person('You', 24);
// We are creating a new person named "You" aged 24.

</pre>

<p><strong>Once created</strong>, an object's properties can again be accessed in one of two ways:</p>

<pre class="brush: js notranslate">// dot notation
obj.name = 'Simon';
var name = obj.name;
</pre>

<p>And...</p>

<pre class="brush: js notranslate">// bracket notation
obj['name'] = 'Simon';
var name = obj['name'];
// can use a variable to define a key
var user = prompt('what is your key?')
obj[user] = prompt('what is its value?')
</pre>

<p>These are also semantically equivalent. The second method has the advantage that the name of the property is provided as a string, which means it can be calculated at run-time. However, using this method prevents some JavaScript engine and minifier optimizations being applied. It can also be used to set and get properties with names that are <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords" title="/en/JavaScript/Reference/Reserved_Words">reserved words</a>:</p>

<pre class="brush: js notranslate">obj.for = 'Simon'; // Syntax error, because 'for' is a reserved word
obj['for'] = 'Simon'; // works fine
</pre>

<div class="note">
<p>Starting in ECMAScript 5, reserved words may be used as object property names "in the buff". This means that they don't need to be "clothed" in quotes when defining object literals. See the ES5 <a href="http://es5.github.io/#x7.6.1">Spec</a>.</p>
</div>

<p>For more on objects and prototypes see <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype">Object.prototype</a>. For an explanation of object prototypes and the object prototype chains see <a href="/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">Inheritance and the prototype chain</a>.</p>

<div class="note">
<p>Starting in ECMAScript 2015, object keys can be defined by the variable using bracket notation upon being created. <code>{[phoneType]: 12345}</code> is possible instead of just <code>var userPhone = {}; userPhone[phoneType] = 12345</code>.</p>
</div>

<h2 id="Arrays">Arrays</h2>

<p>Arrays in JavaScript are actually a special type of object. They work very much like regular objects (numerical properties can naturally be accessed only using <code>[]</code> syntax) but they have one magic property called '<code>length</code>'. This is always one more than the highest index in the array.</p>

<p>One way of creating arrays is as follows:</p>

<pre class="brush: js notranslate">var a = new Array();
a[0] = 'dog';
a[1] = 'cat';
a[2] = 'hen';
a.length; // 3
</pre>

<p>A more convenient notation is to use an array literal:</p>

<pre class="brush: js notranslate">var a = ['dog', 'cat', 'hen'];
a.length; // 3
</pre>

<p>Note that <code>array.length</code> isn't necessarily the number of items in the array. Consider the following:</p>

<pre class="brush: js notranslate">var a = ['dog', 'cat', 'hen'];
a[100] = 'fox';
a.length; // 101
</pre>

<p>Remember — the length of the array is one more than the highest index.</p>

<p>If you query a non-existent array index, you'll get a value of <code>undefined</code> in return:</p>

<pre class="brush: js notranslate">typeof a[90]; // undefined
</pre>

<p>If you take the above about <code>[]</code> and <code>length</code> into account, you can iterate over an array using the following <code>for</code> loop:</p>

<pre class="brush: js notranslate">for (var i = 0; i &lt; a.length; i++) {
  // Do something with a[i]
}
</pre>

<p>ES2015 introduced the more concise <a href="/en-US/docs/Web/JavaScript/Reference/Statements/for...of"><code>for</code>...<code>of</code></a> loop for iterable objects such as arrays:</p>

<pre class="brush:js notranslate">for (const currentValue of a) {
  // Do something with currentValue
}</pre>

<p>You could also iterate over an array using a <a href="/en-US/docs/Web/JavaScript/Reference/Statements/for...in" title="/en/JavaScript/Reference/Statements/for...in"><code>for</code>...<code>in</code></a> loop, however this does not iterate over the array elements, but the array indices. Furthermore, if someone added new properties to <code>Array.prototype</code>, they would also be iterated over by such a loop. Therefore this loop type is not recommended for arrays.</p>

<p>Another way of iterating over an array that was added with ECMAScript 5 is <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">forEach()</a></code>:</p>

<pre class="brush: js notranslate">['dog', 'cat', 'hen'].forEach(function(currentValue, index, array) {
  // Do something with currentValue or array[index]
});
</pre>

<p>If you want to append an item to an array simply do it like this:</p>

<pre class="brush: js notranslate">a.push(item);</pre>

<p>Arrays come with a number of methods. See also the <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">full documentation for array methods</a>.</p>

<table>
 <thead>
  <tr>
   <th scope="col">Method name</th>
   <th scope="col">Description</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>a.toString()</code></td>
   <td>Returns a string with the <code>toString()</code> of each element separated by commas.</td>
  </tr>
  <tr>
   <td><code>a.toLocaleString()</code></td>
   <td>Returns a string with the <code>toLocaleString()</code> of each element separated by commas.</td>
  </tr>
  <tr>
   <td><code>a.concat(item1[, item2[, ...[, itemN]]])</code></td>
   <td>Returns a new array with the items added on to it.</td>
  </tr>
  <tr>
   <td><code>a.join(sep)</code></td>
   <td>Converts the array to a string — with values delimited by the <code>sep</code> param</td>
  </tr>
  <tr>
   <td><code>a.pop()</code></td>
   <td>Removes and returns the last item.</td>
  </tr>
  <tr>
   <td><code>a.push(item1, ..., itemN)</code></td>
   <td>Appends items to the end of the array.</td>
  </tr>
  <tr>
   <td><code>a.reverse()</code></td>
   <td>Reverses the array.</td>
  </tr>
  <tr>
   <td><code>a.shift()</code></td>
   <td>Removes and returns the first item.</td>
  </tr>
  <tr>
   <td><code>a.slice(start[, end])</code></td>
   <td>Returns a sub-array.</td>
  </tr>
  <tr>
   <td><code>a.sort([cmpfn])</code></td>
   <td>Takes an optional comparison function.</td>
  </tr>
  <tr>
   <td><code>a.splice(start, delcount[, item1[, ...[, itemN]]])</code></td>
   <td>Lets you modify an array by deleting a section and replacing it with more items.</td>
  </tr>
  <tr>
   <td><code>a.unshift(item1[, item2[, ...[, itemN]]])</code></td>
   <td>Prepends items to the start of the array.</td>
  </tr>
 </tbody>
</table>

<h2 id="Functions">Functions</h2>

<p>Along with objects, functions are the core component in understanding JavaScript. The most basic function couldn't be much simpler:</p>

<pre class="brush: js notranslate">function add(x, y) {
  var total = x + y;
  return total;
}
</pre>

<p>This demonstrates a basic function. A JavaScript function can take 0 or more named parameters. The function body can contain as many statements as you like and can declare its own variables which are local to that function. The <code>return</code> statement can be used to return a value at any time, terminating the function. If no return statement is used (or an empty return with no value), JavaScript returns <code>undefined</code>.</p>

<p>The named parameters turn out to be more like guidelines than anything else. You can call a function without passing the parameters it expects, in which case they will be set to <code>undefined</code>.</p>

<pre class="brush: js notranslate">add(); // NaN
// You can't perform addition on undefined
</pre>

<p>You can also pass in more arguments than the function is expecting:</p>

<pre class="brush: js notranslate">add(2, 3, 4); // 5
// added the first two; 4 was ignored
</pre>

<p>That may seem a little silly, but functions have access to an additional variable inside their body called <a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments" title="/en/JavaScript/Reference/Functions_and_function_scope/arguments"><code>arguments</code></a>, which is an array-like object holding all of the values passed to the function. Let's re-write the add function to take as many values as we want:</p>

<pre class="brush: js notranslate">function add() {
  var sum = 0;
  for (var i = 0, j = arguments.length; i &lt; j; i++) {
    sum += arguments[i];
  }
  return sum;
}

add(2, 3, 4, 5); // 14
</pre>

<p>That's really not any more useful than writing <code>2 + 3 + 4 + 5</code> though. Let's create an averaging function:</p>

<pre class="brush: js notranslate">function avg() {
  var sum = 0;
  for (var i = 0, j = arguments.length; i &lt; j; i++) {
    sum += arguments[i];
  }
  return sum / arguments.length;
}

avg(2, 3, 4, 5); // 3.5
</pre>

<p>This is pretty useful, but it does seem a little verbose. To reduce this code a bit more we can look at substituting the use of the arguments array through <a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">Rest parameter syntax</a>. In this way, we can pass in any number of arguments into the function while keeping our code minimal. The <strong>rest parameter operator</strong> is used in function parameter lists with the format: <strong>...variable</strong> and it will include within that variable the entire list of uncaptured arguments that the function was called with. We will also replace the <strong>for</strong> loop with a <strong>for...of</strong> loop to return the values within our variable.</p>

<pre class="brush: js notranslate">function avg(...args) {
  var sum = 0;
  for (let value of args) {
    sum += value;
  }
  return sum / args.length;
}

avg(2, 3, 4, 5); // 3.5
</pre>

<div class="note">In the above code, the variable <strong>args</strong> holds all the values that were passed into the function.<br>
<br>
It is important to note that wherever the rest parameter operator is placed in a function declaration it will store all arguments <em>after</em> its declaration, but not before. <em>i.e. function</em> <em>avg(</em><strong>firstValue, </strong><em>...args)</em><strong> </strong>will store the first value passed into the function in the <strong>firstValue </strong>variable and the remaining arguments in <strong>args</strong>. That's another useful language feature but it does lead us to a new problem. The <code>avg()</code> function takes a comma-separated list of arguments — but what if you want to find the average of an array? You could just rewrite the function as follows:</div>

<pre class="brush: js notranslate">function avgArray(arr) {
  var sum = 0;
  for (var i = 0, j = arr.length; i &lt; j; i++) {
    sum += arr[i];
  }
  return sum / arr.length;
}

avgArray([2, 3, 4, 5]); // 3.5
</pre>

<p>But it would be nice to be able to reuse the function that we've already created. Luckily, JavaScript lets you call a function with an arbitrary array of arguments, using the {{jsxref("Function.apply", "apply()")}} method of any function object.</p>

<pre class="brush: js notranslate">avg.apply(null, [2, 3, 4, 5]); // 3.5
</pre>

<p>The second argument to <code>apply()</code> is the array to use as arguments; the first will be discussed later on. This emphasizes the fact that functions are objects too.</p>

<div class="note">
<p>You can achieve the same result using the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">spread operator</a> in the function call.</p>

<p>For instance: <code>avg(...numbers)</code></p>
</div>

<p>JavaScript lets you create anonymous functions.</p>

<pre class="brush: js notranslate">var avg = function() {
  var sum = 0;
  for (var i = 0, j = arguments.length; i &lt; j; i++) {
    sum += arguments[i];
  }
  return sum / arguments.length;
};
</pre>

<p>This is semantically equivalent to the <code>function avg()</code> form. It's extremely powerful, as it lets you put a full function definition anywhere that you would normally put an expression. This enables all sorts of clever tricks. Here's a way of "hiding" some local variables — like block scope in C:</p>

<pre class="brush: js notranslate">var a = 1;
var b = 2;

(function() {
  var b = 3;
  a += b;
})();

a; // 4
b; // 2
</pre>

<p>JavaScript allows you to call functions recursively. This is particularly useful for dealing with tree structures, such as those found in the browser DOM.</p>

<pre class="brush: js notranslate">function countChars(elm) {
  if (elm.nodeType == 3) { // TEXT_NODE
    return elm.nodeValue.length;
  }
  var count = 0;
  for (var i = 0, child; child = elm.childNodes[i]; i++) {
    count += countChars(child);
  }
  return count;
}
</pre>

<p>This highlights a potential problem with anonymous functions: how do you call them recursively if they don't have a name? JavaScript lets you name function expressions for this. You can use named <a href="/en-US/docs/Glossary/IIFE">IIFEs (Immediately Invoked Function Expressions)</a> as shown below:</p>

<pre class="brush: js notranslate">var charsInBody = (function counter(elm) {
  if (elm.nodeType == 3) { // TEXT_NODE
    return elm.nodeValue.length;
  }
  var count = 0;
  for (var i = 0, child; child = elm.childNodes[i]; i++) {
    count += counter(child);
  }
  return count;
})(document.body);
</pre>

<p>The name provided to a function expression as above is only available to the function's own scope. This allows more optimizations to be done by the engine and results in more readable code. The name also shows up in the debugger and some stack traces, which can save you time when debugging.</p>

<p>Note that JavaScript functions are themselves objects — like everything else in JavaScript — and you can add or change properties on them just like we've seen earlier in the Objects section.</p>

<h2 id="Custom_objects">Custom objects</h2>

<div class="note">For a more detailed discussion of object-oriented programming in JavaScript, see <a href="/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript">Introduction to Object-Oriented JavaScript</a>.</div>

<p>In classic Object Oriented Programming, objects are collections of data and methods that operate on that data. JavaScript is a prototype-based language that contains no class statement, as you'd find in C++ or Java (this is sometimes confusing for programmers accustomed to languages with a class statement). Instead, JavaScript uses functions as classes. Let's consider a person object with first and last name fields. There are two ways in which the name might be displayed: as "first last" or as "last, first". Using the functions and objects that we've discussed previously, we could display the data like this:</p>

<pre class="brush: js notranslate">function makePerson(first, last) {
  return {
    first: first,
    last: last
  };
}
function personFullName(person) {
  return person.first + ' ' + person.last;
}
function personFullNameReversed(person) {
  return person.last + ', ' + person.first;
}

var s = makePerson('Simon', 'Willison');
personFullName(s); // "Simon Willison"
personFullNameReversed(s); // "Willison, Simon"
</pre>

<p>This works, but it's pretty ugly. You end up with dozens of functions in your global namespace. What we really need is a way to attach a function to an object. Since functions are objects, this is easy:</p>

<pre class="brush: js notranslate">function makePerson(first, last) {
  return {
    first: first,
    last: last,
    fullName: function() {
      return this.first + ' ' + this.last;
    },
    fullNameReversed: function() {
      return this.last + ', ' + this.first;
    }
  };
}

var s = makePerson('Simon', 'Willison');
s.fullName(); // "Simon Willison"
s.fullNameReversed(); // "Willison, Simon"
</pre>

<p>Note on the <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/this" title="/en/JavaScript/Reference/Operators/this">this</a></code> keyword. Used inside a function, <code>this</code> refers to the current object. What that actually means is specified by the way in which you called that function. If you called it using <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Accessing_properties" title="/en/JavaScript/Reference/Operators/Member_Operators">dot notation or bracket notation</a> on an object, that object becomes <code>this</code>. If dot notation wasn't used for the call, <code>this</code> refers to the global object.</p>

<p>Note that <code>this</code> is a frequent cause of mistakes. For example:</p>

<pre class="brush: js notranslate">var s = makePerson('Simon', 'Willison');
var fullName = s.fullName;
fullName(); // undefined undefined
</pre>

<p>When we call <code>fullName()</code> alone, without using <code>s.fullName()</code>, <code>this</code> is bound to the global object. Since there are no global variables called <code>first</code> or <code>last</code> we get <code>undefined</code> for each one.</p>

<p>We can take advantage of the <code>this</code> keyword to improve our <code>makePerson</code> function:</p>

<pre class="brush: js notranslate">function Person(first, last) {
  this.first = first;
  this.last = last;
  this.fullName = function() {
    return this.first + ' ' + this.last;
  };
  this.fullNameReversed = function() {
    return this.last + ', ' + this.first;
  };
}
var s = new Person('Simon', 'Willison');
</pre>

<p>We have introduced another keyword: <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/new" title="/en/JavaScript/Reference/Operators/new">new</a></code>. <code>new</code> is strongly related to <code>this</code>. It creates a brand new empty object, and then calls the function specified, with <code>this</code> set to that new object. Notice though that the function specified with <code>this</code> does not return a value but merely modifies the <code>this</code> object. It's <code>new</code> that returns the <code>this</code> object to the calling site. Functions that are designed to be called by <code>new</code> are called constructor functions. Common practice is to capitalize these functions as a reminder to call them with <code>new</code>.</p>

<p>The improved function still has the same pitfall with calling <code>fullName()</code> alone.</p>

<p>Our person objects are getting better, but there are still some ugly edges to them. Every time we create a person object we are creating two brand new function objects within it — wouldn't it be better if this code was shared?</p>

<pre class="brush: js notranslate">function personFullName() {
  return this.first + ' ' + this.last;
}
function personFullNameReversed() {
  return this.last + ', ' + this.first;
}
function Person(first, last) {
  this.first = first;
  this.last = last;
  this.fullName = personFullName;
  this.fullNameReversed = personFullNameReversed;
}
</pre>

<p>That's better: we are creating the method functions only once, and assigning references to them inside the constructor. Can we do any better than that? The answer is yes:</p>

<pre class="brush: js notranslate">function Person(first, last) {
  this.first = first;
  this.last = last;
}
Person.prototype.fullName = function() {
  return this.first + ' ' + this.last;
};
Person.prototype.fullNameReversed = function() {
  return this.last + ', ' + this.first;
};
</pre>

<p><code>Person.prototype</code> is an object shared by all instances of <code>Person</code>. It forms part of a lookup chain (that has a special name, "prototype chain"): any time you attempt to access a property of <code>Person</code> that isn't set, JavaScript will check <code>Person.prototype</code> to see if that property exists there instead. As a result, anything assigned to <code>Person.prototype</code> becomes available to all instances of that constructor via the <code>this</code> object.</p>

<p>This is an incredibly powerful tool. JavaScript lets you modify something's prototype at any time in your program, which means you can add extra methods to existing objects at runtime:</p>

<pre class="brush: js notranslate">var s = new Person('Simon', 'Willison');
s.firstNameCaps(); // TypeError on line 1: s.firstNameCaps is not a function

Person.prototype.firstNameCaps = function() {
  return this.first.toUpperCase();
};
s.firstNameCaps(); // "SIMON"
</pre>

<p>Interestingly, you can also add things to the prototype of built-in JavaScript objects. Let's add a method to <code>String</code> that returns that string in reverse:</p>

<pre class="brush: js notranslate">var s = 'Simon';
s.reversed(); // TypeError on line 1: s.reversed is not a function

String.prototype.reversed = function() {
  var r = '';
  for (var i = this.length - 1; i &gt;= 0; i--) {
    r += this[i];
  }
  return r;
};

s.reversed(); // nomiS
</pre>

<p>Our new method even works on string literals!</p>

<pre class="brush: js notranslate">'This can now be reversed'.reversed(); // desrever eb won nac sihT
</pre>

<p>As mentioned before, the prototype forms part of a chain. The root of that chain is <code>Object.prototype</code>, whose methods include <code>toString()</code> — it is this method that is called when you try to represent an object as a string. This is useful for debugging our <code>Person</code> objects:</p>

<pre class="brush: js notranslate">var s = new Person('Simon', 'Willison');
s.toString(); // [object Object]

Person.prototype.toString = function() {
  return '&lt;Person: ' + this.fullName() + '&gt;';
}

s.toString(); // "&lt;Person: Simon Willison&gt;"
</pre>

<p>Remember how <code>avg.apply()</code> had a null first argument? We can revisit that now. The first argument to <code>apply()</code> is the object that should be treated as '<code>this</code>'. For example, here's a trivial implementation of <code>new</code>:</p>

<pre class="brush: js notranslate">function trivialNew(constructor, ...args) {
  var o = {}; // Create an object
  constructor.apply(o, args);
  return o;
}
</pre>

<p>This isn't an exact replica of <code>new</code> as it doesn't set up the prototype chain (it would be difficult to illustrate). This is not something you use very often, but it's useful to know about. In this snippet, <code>...args</code> (including the ellipsis) is called the "<a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest arguments</a>" — as the name implies, this contains the rest of the arguments.</p>

<p>Calling</p>

<pre class="brush: js notranslate">var bill = trivialNew(Person, 'William', 'Orange');</pre>

<p>is therefore almost equivalent to</p>

<pre class="brush: js notranslate">var bill = new Person('William', 'Orange');</pre>

<p><code>apply()</code> has a sister function named <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call" title="/en/JavaScript/Reference/Global_Objects/Function/call"><code>call</code></a>, which again lets you set <code>this</code> but takes an expanded argument list as opposed to an array.</p>

<pre class="brush: js notranslate">function lastNameCaps() {
  return this.last.toUpperCase();
}
var s = new Person('Simon', 'Willison');
lastNameCaps.call(s);
// Is the same as:
s.lastNameCaps = lastNameCaps;
s.lastNameCaps(); // WILLISON
</pre>

<h3 id="Inner_functions">Inner functions</h3>

<p>JavaScript function declarations are allowed inside other functions. We've seen this once before, with an earlier <code>makePerson()</code> function. An important detail of nested functions in JavaScript is that they can access variables in their parent function's scope:</p>

<pre class="brush: js notranslate">function parentFunc() {
  var a = 1;

  function nestedFunc() {
    var b = 4; // parentFunc can't use this
    return a + b;
  }
  return nestedFunc(); // 5
}
</pre>

<p>This provides a great deal of utility in writing more maintainable code. If a called function relies on one or two other functions that are not useful to any other part of your code, you can nest those utility functions inside it. This keeps the number of functions that are in the global scope down, which is always a good thing.</p>

<p>This is also a great counter to the lure of global variables. When writing complex code it is often tempting to use global variables to share values between multiple functions — which leads to code that is hard to maintain. Nested functions can share variables in their parent, so you can use that mechanism to couple functions together when it makes sense without polluting your global namespace — "local globals" if you like. This technique should be used with caution, but it's a useful ability to have.</p>

<h2 id="Closures">Closures</h2>

<p>This leads us to one of the most powerful abstractions that JavaScript has to offer — but also the most potentially confusing. What does this do?</p>

<pre class="brush: js notranslate">function makeAdder(a) {
  return function(b) {
    return a + b;
  };
}
var add5 = makeAdder(5);
var add20 = makeAdder(20);
add5(6); // ?
add20(7); // ?
</pre>

<p>The name of the <code>makeAdder()</code> function should give it away: it creates new 'adder' functions, each of which, when called with one argument, adds it to the argument that it was created with.</p>

<p>What's happening here is pretty much the same as was happening with the inner functions earlier on: a function defined inside another function has access to the outer function's variables. The only difference here is that the outer function has returned, and hence common sense would seem to dictate that its local variables no longer exist. But they <em>do</em> still exist — otherwise, the adder functions would be unable to work. What's more, there are two different "copies" of <code>makeAdder()</code>'s local variables — one in which <code>a</code> is 5 and the other one where <code>a</code> is 20. So the result of that function calls is as follows:</p>

<pre class="brush: js notranslate">add5(6); // returns 11
add20(7); // returns 27
</pre>

<p>Here's what's actually happening. Whenever JavaScript executes a function, a 'scope' object is created to hold the local variables created within that function. It is initialized with any variables passed in as function parameters. This is similar to the global object that all global variables and functions live in, but with a couple of important differences: firstly, a brand new scope object is created every time a function starts executing, and secondly, unlike the global object (which is accessible as <code>this</code> and in browsers as <code>window</code>) these scope objects cannot be directly accessed from your JavaScript code. There is no mechanism for iterating over the properties of the current scope object, for example.</p>

<p>So when <code>makeAdder()</code> is called, a scope object is created with one property: <code>a</code>, which is the argument passed to the <code>makeAdder()</code> function. <code>makeAdder()</code> then returns a newly created function. Normally JavaScript's garbage collector would clean up the scope object created for <code>makeAdder()</code> at this point, but the returned function maintains a reference back to that scope object. As a result, the scope object will not be garbage-collected until there are no more references to the function object that <code>makeAdder()</code> returned.</p>

<p>Scope objects form a chain called the scope chain, similar to the prototype chain used by JavaScript's object system.</p>

<p>A <strong>closure</strong> is the combination of a function and the scope object in which it was created. Closures let you save state — as such, they can often be used in place of objects. You can find <a href="http://stackoverflow.com/questions/111102/how-do-javascript-closures-work">several excellent introductions to closures</a>.</p>

<div id="gtx-trans" style="position: absolute; left: 72px; top: 4643px;">
<div class="gtx-trans-icon"></div>
</div>