You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -376,73 +376,143 @@ In the very first chapter about [variables](info:variables), we mentioned three
376
376
377
377
Here we only talked about `let`. But `const` behaves totally the same way in terms of Lexical Environments.
378
378
379
-
The `var` is a completely different beast, coming from old times. It is usually not used in modern scripts, but still lurks in the old ones.
379
+
The `var` is a very different beast, coming from old times. It's generally not used in modern scripts, but still lurks in the old ones.
380
380
381
-
**A `var` variable only recognizes function and global Lexical Environments, not blocks.**
381
+
If you don't plan meeting such scripts you may even skip this subsection and return if/when this beasts bites
382
382
383
-
For instance:
383
+
From the first sight, `var` behaves similar to `let`:
384
384
385
-
```js
386
-
if (true) {
387
-
var test =true; // use "var" instead of "let"
385
+
```js run
386
+
functionsayHi() {
387
+
var phrase ="Hello"; // local variable, "var" instead of "let"
388
+
389
+
alert(phrase); // Hello
388
390
}
389
391
390
-
*!*
391
-
alert(test); // true, variable lives after if
392
-
*/!*
392
+
sayHi();
393
+
394
+
alert(phrase); // Error, phrase is not defined
393
395
```
394
396
395
-
If we used `let test`, then it wouldn't be visible to `alert`. But `var` variables ignore code blocks, so here we've got a global `test`.
397
+
...But let's list the differences.
396
398
397
-
The same thing for loops:
399
+
`var` variables only recognize function and global Lexical Environments, they ignore blocks.
400
+
: For instance:
398
401
399
-
```js
400
-
for(var i =0; i <10; i++) {
401
-
//...
402
-
}
402
+
```js
403
+
if (true) {
404
+
var test = true; // use "var" instead of "let"
405
+
}
403
406
404
-
*!*
405
-
alert(i); //10, visible after loop, global variable
406
-
*/!*
407
-
```
407
+
*!*
408
+
alert(test); // true, the variable lives after if
409
+
*/!*
410
+
```
408
411
409
-
The only Lexical Environment respected by `var` is function.
412
+
If we used `let test`, then it wouldn't be visible to `alert`. But `var` variables ignore code blocks, so here we've got a global `test`.
410
413
411
-
So here it behaves the same way as `let`:
414
+
The same thing for loops:
412
415
413
-
```js run
414
-
functionsayHi() {
415
-
var phrase ="Hello"; // local variable
416
+
```js
417
+
for(var i = 0; i < 10; i++) {
418
+
// ...
419
+
}
416
420
417
-
alert(phrase); // Hello
418
-
}
421
+
*!*
422
+
alert(i); // 10, "i" is visible after loop, it's a global variable
423
+
*/!*
424
+
```
419
425
420
-
sayHi();
426
+
As we can see, `var` pierces through `if`, `for` or other code blocks. That's because some time ago, in Javascript blocks had no Lexical Environments. And `var` is a reminiscence of that.
421
427
422
-
alert(phrase); // Error, phrase is not defined
423
-
```
428
+
`var` declarations are processed when the function starts (or when the script starts for globals).
429
+
: Technically, it means that all `var` variables are defined from the beginning of the function.
424
430
425
-
HOISTED
431
+
So this code:
426
432
433
+
```js
434
+
function sayHi() {
435
+
phrase = "Hello";
427
436
437
+
alert(phrase);
428
438
439
+
*!*
440
+
var phrase;
441
+
*/!*
442
+
}
443
+
```
429
444
445
+
...Is technically the same as:
430
446
447
+
```js
448
+
function sayHi() {
449
+
*!*
450
+
var phrase;
451
+
*/!*
452
+
phrase = "Hello";
453
+
454
+
alert(phrase);
455
+
}
456
+
```
431
457
458
+
...Or even like this (remember, code blocks are ignored):
432
459
460
+
```js
461
+
function sayHi() {
462
+
phrase = "Hello";
463
+
464
+
*!*
465
+
if (false) {
466
+
var phrase;
467
+
}
468
+
*/!*
469
+
470
+
alert(phrase);
471
+
}
472
+
```
433
473
474
+
People also call such behavior "hoisting" (raising), because all `var` are "hoisted" (raised) to the top of the function.
434
475
476
+
**The pitfall is that assignments are not hoisted**.
435
477
478
+
For instance:
436
479
437
-
**The `var` variables are "hoisted" to the top of functions.**
480
+
```js run
481
+
function sayHi() {
482
+
alert(phrase);
438
483
439
-
In other words, a `var` declaration is processed in the beginning of the function (or the whole script for globals).
484
+
*!*
485
+
var phrase = "Hello";
486
+
*/!*
487
+
}
488
+
489
+
sayHi();
490
+
```
491
+
492
+
The line `var phrase = "Hello"` has two actions in it: variable declaration and assignment.
493
+
494
+
The declaration is hoisted, but the assignment is not. The `alert` works, because the variable is defined from the start of the function. But its value is assigned below, so it shows `undefined`.
495
+
496
+
The code is essentially the same as:
497
+
498
+
```js run
499
+
function sayHi() {
500
+
*!*
501
+
var phrase;
502
+
*/!*
503
+
504
+
alert(phrase); // undefined
505
+
506
+
phrase = "Hello";
507
+
}
508
+
509
+
sayHi();
510
+
```
511
+
512
+
The features described above make using `var` inconvenient most of time. Because we can't create block-local variables. And hoisting just creates more space for errors. So, once again, nowadays, `vars` are used exceptionally rarely. But they exist in old scripts.
440
513
441
-
It popu
442
514
443
-
These
444
515
445
-
So, it is visible outside of blocks, for instance:
446
516
447
517
## Global object
448
518
@@ -455,8 +525,9 @@ As described in the [specification](https://tc39.github.io/ecma262/#sec-lexical-
455
525
The key word here is "some". In practice:
456
526
457
527
-`Array`, `Object`, `alert`, `prompt` and other built built-in functions and variables and Function Decla
0 commit comments