This commit is contained in:
Ilya Kantor 2019-12-26 14:59:57 +03:00
parent 5b195795da
commit 964ed57c42
39 changed files with 365 additions and 461 deletions

View file

@ -1,6 +1,12 @@
# The old "var"
```smart header="This article is for understanding old scripts"
The information in this article is useful for understanding old scripts.
That's not how we write a new code.
```
In the very first chapter about [variables](info:variables), we mentioned three ways of variable declaration:
1. `let`
@ -188,6 +194,74 @@ Because all `var` declarations are processed at the function start, we can refer
In both examples above `alert` runs without an error, because the variable `phrase` exists. But its value is not yet assigned, so it shows `undefined`.
### IIFE
As in the past there was only `var`, and it has no block-level visibility, programmers invented a way to emulate it. What they did was called "immediately-invoked function expressions" (abbreviated as IIFE).
That's not something we should use nowadays, but you can find them in old scripts.
An IIFE looks like this:
```js run
(function() {
let message = "Hello";
alert(message); // Hello
})();
```
Here a Function Expression is created and immediately called. So the code executes right away and has its own private variables.
The Function Expression is wrapped with parenthesis `(function {...})`, because when JavaScript meets `"function"` in the main code flow, it understands it as the start of a Function Declaration. But a Function Declaration must have a name, so this kind of code will give an error:
```js run
// Try to declare and immediately call a function
function() { // <-- Error: Unexpected token (
let message = "Hello";
alert(message); // Hello
}();
```
Even if we say: "okay, let's add a name", that won't work, as JavaScript does not allow Function Declarations to be called immediately:
```js run
// syntax error because of parentheses below
function go() {
}(); // <-- can't call Function Declaration immediately
```
So, the parentheses around the function is a trick to show JavaScript that the function is created in the context of another expression, and hence it's a Function Expression: it needs no name and can be called immediately.
There exist other ways besides parentheses to tell JavaScript that we mean a Function Expression:
```js run
// Ways to create IIFE
(function() {
alert("Parentheses around the function");
}*!*)*/!*();
(function() {
alert("Parentheses around the whole thing");
}()*!*)*/!*;
*!*!*/!*function() {
alert("Bitwise NOT operator starts the expression");
}();
*!*+*/!*function() {
alert("Unary plus starts the expression");
}();
```
In all the above cases we declare a Function Expression and run it immediately. Let's note again: nowadays there's no reason to write such code.
## Summary
There are two main differences of `var` compared to `let/const`:
@ -195,6 +269,6 @@ There are two main differences of `var` compared to `let/const`:
1. `var` variables have no block scope, they are visible minimum at the function level.
2. `var` declarations are processed at function start (script start for globals).
There's one more minor difference related to the global object, we'll cover that in the next chapter.
There's one more very minor difference related to the global object, that we'll cover in the next chapter.
These differences make `var` worse than `let` most of the time. Block-level variables is such a great thing. That's why `let` was introduced in the standard long ago, and is now a major way (along with `const`) to declare a variable.