@@ -295,7 +295,7 @@ <h1>JavaScript Garden</h1>
295
295
</ section > < section > < header > < h3 > The < code > function</ code > declaration</ h3 > </ header >
296
296
< pre > < code > function foo() {}
297
297
</ code > </ pre >
298
- < p > The above function gets created < strong > before </ strong > the execution of the program starts;
298
+ < p > The above function gets < a href =" #scopes " > hoisted </ a > before the execution of the program starts;
299
299
thus, it is available < em > everywhere</ em > in the scope it was < em > defined</ em > in, even if
300
300
called before the actual definition in the source.</ p >
301
301
< pre > < code > foo(); // Works because foo was created before this code runs
@@ -309,9 +309,9 @@ <h1>JavaScript Garden</h1>
309
309
foo(); // this raises a TypeError
310
310
var foo = function() {};
311
311
</ code > </ pre >
312
- < p > Due to the fact that < code > var</ code > is a < em > statement </ em > , which - just like the function
313
- declaration - creates the variable < code > foo</ code > before the actual execution of the code
314
- starts, < code > foo </ code > is already defined when the script gets executed.</ p >
312
+ < p > Due to the fact that < code > var</ code > is a declaration, that hoists the variable name < code > foo </ code >
313
+ before the actual execution of the code starts, < code > foo</ code > is already defined when
314
+ the script gets executed.</ p >
315
315
< p > But since assignments only happens at runtime, the value of < code > foo</ code > will default
316
316
to < a href ="#undefined "> undefined</ a > before the corresponding code is executed.</ p >
317
317
</ section > < section > < header > < h3 > Named function expression</ h3 > </ header >
@@ -324,38 +324,7 @@ <h1>JavaScript Garden</h1>
324
324
< p > Here < code > bar</ code > is not available in the outer scope, since the function only gets
325
325
assigned to < code > foo</ code > ; however, inside of < code > bar</ code > it is available. This is due to
326
326
how < a href ="#scopes "> name resolution</ a > in JavaScript works, the name of the function
327
- is < em > always</ em > made available in the local scope of the function itself.</ p >
328
- </ section > < section > < header > < h3 > The < code > var</ code > statement</ h3 > </ header >
329
- < pre > < code > function test() {
330
- if (foo) {
331
- bar = 2;
332
-
333
- } else {
334
- var bar = 1;
335
- }
336
- return foo;
337
- }
338
-
339
- if (false) {
340
- var foo = 1;
341
- }
342
- </ code > </ pre >
343
- < p > Since there is < strong > no</ strong > < a href ="#scopes "> block scope</ a > in JavaScript, the above will
344
- < strong > not</ strong > assign the value < code > 2</ code > to the < em > global</ em > variable < code > bar</ code > . Instead, it will
345
- assign the value of < code > 2</ code > to the < em > local</ em > variable < code > bar</ code > of < code > test</ code > . </ p >
346
- < p > Also, while the statements inside the < code > if</ code > block never get executed, the variable
347
- < code > foo</ code > still gets created and defaults to the value of < code > undefined</ code > ; again, this
348
- is due to the lack of block scoping and the workings of hoisting.</ p >
349
- </ section > < section > < header > < h3 > Order of parsing</ h3 > </ header >
350
- < p > All < code > var</ code > statements get parsed < strong > before</ strong > < code > function</ code > declarations; hence,
351
- subsequent statements will override the previous ones.</ p >
352
- < pre > < code > function foo() {}
353
- var foo;
354
-
355
- foo; // [function foo]
356
- var foo = 2;
357
- foo; // 2
358
- </ code > </ pre > </ section > </ article >
327
+ is < em > always</ em > made available in the local scope of the function itself.</ p > </ section > </ article >
359
328
360
329
< article > < section > < header > < h2 id ="this "> How < code > this</ code > works < a href ="#intro "> #top</ a > </ h2 > </ header >
361
330
< p > JavaScript has a different concept of what the special name < code > this</ code > refers to
@@ -711,6 +680,76 @@ <h1>JavaScript Garden</h1>
711
680
</ code > </ pre >
712
681
< p > While < code > foo</ code > and < code > i</ code > are local variables inside the scope of the function < code > test</ code > ,
713
682
the assignment of < code > bar</ code > will override the global variable with the same name.</ p >
683
+ </ section > < section > < header > < h3 > Hoisting</ h3 > </ header >
684
+ < p > JavaScript < strong > hoists</ strong > declarations. This means that both < code > var</ code > statements and
685
+ < code > function</ code > declarations will be moved to the top of their enclosing scope.</ p >
686
+ < pre > < code > bar();
687
+ var bar = function() {};
688
+ var someValue = 42;
689
+
690
+ test();
691
+ function test(data) {
692
+ if (false) {
693
+ goo = 1;
694
+
695
+ } else {
696
+ var goo = 2;
697
+ }
698
+ for(var i = 0; i < 100; i++) {
699
+ var e = data[i];
700
+ }
701
+ }
702
+ </ code > </ pre >
703
+ < p > The above code gets transformed before any execution is started. JavaScript moves
704
+ the < code > var</ code > statements as well as the < code > function</ code > declarations to the top of the
705
+ nearest surrounding scope.</ p >
706
+ < pre > < code > // var statements got moved here
707
+ var bar, someValue; // default to 'undefined'
708
+
709
+ // the function declartion got moved up too
710
+ function test(data) {
711
+ var goo, i, e; // missing block scope moves these here
712
+ if (false) {
713
+ goo = 1;
714
+
715
+ } else {
716
+ goo = 2;
717
+ }
718
+ for(i = 0; i < 100; i++) {
719
+ e = data[i];
720
+ }
721
+ }
722
+
723
+ bar(); // fails with a TypeError since bar is still 'undefined'
724
+ someValue = 42; // assignments are not affected by hoisting
725
+ bar = function() {};
726
+
727
+ test();
728
+ </ code > </ pre >
729
+ < p > Missing block scoping will not only move < code > var</ code > statements out of loops and
730
+ their bodies, it will also make the results of certain < code > if</ code > constructs
731
+ non-intuitive.</ p >
732
+ < p > In the original code the < code > if</ code > statement seemed to modify the < em > global
733
+ variable</ em > < code > goo</ code > , while actually it modifies the < em > local variable</ em > - after hoisting
734
+ has been applied.</ p >
735
+ < p > Without the knowledge about < em > hoisting</ em > , below code might seem to raise a
736
+ < code > ReferenceError</ code > .</ p >
737
+ < pre > < code > // check whether SomeImportantThing has been initiliazed
738
+ if (!SomeImportantThing) {
739
+ var SomeImportantThing = {};
740
+ }
741
+ </ code > </ pre >
742
+ < p > But of course, the above works due to the fact that the < code > var</ code > statement is being
743
+ moved to the top of the < em > global scope</ em > .</ p >
744
+ < pre > < code > var SomeImportantThing;
745
+
746
+ // other code might initiliaze SomeImportantThing here, or not
747
+
748
+ // make sure it's there
749
+ if (!SomeImportantThing) {
750
+ SomeImportantThing = {};
751
+ }
752
+ </ code > </ pre >
714
753
</ section > < section > < header > < h3 > Name resolution order</ h3 > </ header >
715
754
< p > All scopes in JavaScript, including the < em > global scope</ em > , have the special name
716
755
< a href ="#this "> < code > this</ code > </ a > defined in them, which refers to the < em > current object</ em > . </ p >
@@ -1051,7 +1090,7 @@ <h1>JavaScript Garden</h1>
1051
1090
< aside >
1052
1091
< p > < strong > Note:</ strong > While < code > typeof</ code > can also be called with a function like syntax
1053
1092
i.e. < code > typeof(obj)</ code > , this is not a function call. The two parenthesis will
1054
- behave like normal and there return value will be used as the operand of the
1093
+ behave like normal and the return value will be used as the operand of the
1055
1094
< code > typeof</ code > operator. There is < strong > no</ strong > < code > typeof</ code > function.</ p >
1056
1095
</ aside >
1057
1096
</ section > < section > < header > < h3 > The JavaScript type table</ h3 > </ header >
@@ -1081,11 +1120,11 @@ <h1>JavaScript Garden</h1>
1081
1120
following strings. < code > Arguments</ code > , < code > Array</ code > , < code > Boolean</ code > , < code > Date</ code > , < code > Error</ code > ,
1082
1121
< code > Function</ code > , < code > JSON</ code > , < code > Math</ code > , < code > Number</ code > , < code > Object</ code > , < code > RegExp</ code > , < code > String</ code > .</ p >
1083
1122
</ aside >
1084
- < p > In order to retrieve the value of < code > [[Class]]</ code > one can has to make use of the
1123
+ < p > In order to retrieve the value of < code > [[Class]]</ code > one has to make use of the
1085
1124
< code > toString</ code > method of < code > Object.prototype</ code > .</ p >
1086
1125
</ section > < section > < header > < h3 > The Class of an object</ h3 > </ header >
1087
1126
< p > The specification gives exactly one way of accessing the < code > [[Class]]</ code > value,
1088
- which the use of < code > Object.prototype.toString</ code > . </ p >
1127
+ with the use of < code > Object.prototype.toString</ code > . </ p >
1089
1128
< pre > < code > function is(type, obj) {
1090
1129
var clas = Object.prototype.toString.call(obj).slice(8, -1);
1091
1130
return obj !== undefined && obj !== null && clas === type;
0 commit comments