var -> et

This commit is contained in:
Ilya Kantor 2015-09-25 13:56:55 +02:00
parent 6a9f66ef27
commit 1d236fddf8
45 changed files with 305 additions and 295 deletions

View file

@ -5,8 +5,14 @@ The [latest standard](http://www.ecma-international.org/publications/standards/E
As it includes a lot of new features, most browsers implement them partially. You can find the current state of the support at [](https://kangax.github.io/compat-table/es6/). As it includes a lot of new features, most browsers implement them partially. You can find the current state of the support at [](https://kangax.github.io/compat-table/es6/).
## Single-engine app
If a project is developed for a single JavaScript engine, like V8 (Node.JS, Chrome), then we can use V8-supported features. That's a lot. If a project is developed for a single JavaScript engine, like V8 (Node.JS, Chrome), then we can use V8-supported features. That's a lot.
Most notably, V8 supports many of the new features only if the code is running in the "strict mode" (modern mode), which should be enabled explicitly using a directive `'use strict';` at the start.
You will find most code in this tutorial using this directive and, because of that, runnable in Chrome.
But what if we're writing a cross-browser application? Different browsers support different subsets of ES-2015. But what if we're writing a cross-browser application? Different browsers support different subsets of ES-2015.
Here comes Babel.JS. Here comes Babel.JS.
@ -68,13 +74,13 @@ That doesn't mean that the example is wrong! It's just the browser lacking the s
[Chrome Canary](https://www.google.com/chrome/browser/canary.html) is recommended, most examples work in it. [Chrome Canary](https://www.google.com/chrome/browser/canary.html) is recommended, most examples work in it.
[Firefox Developer Edition](https://www.mozilla.org/en-US/firefox/channel/#developer) is fine too, but it has certain glitches. Like: [let](/let-const) variables working only with when the script type contains `version=1.7` or `1.8`: `<script type="application/javascript;version=1.7">`. Most other browsers do not understand such script type. This site uses a special trick to workaround. [Firefox Developer Edition](https://www.mozilla.org/en-US/firefox/channel/#developer) is fine too, but it has certain glitches. Like: [let](/let-const) variables working only with when the script type contains `version=1.7` or `1.8`: `<script type="application/javascript;version=1.7">`. Most other browsers do not understand such script type. This site uses a special trick to workaround that, so that the scripts work in both Firefox and other browsers.
And in any case you can go [Babel: try it out](https://babeljs.io/repl/) page and run the example there! And even if your browser does not support some code, you can run it through Babel.JS, on the page [Babel: try it out](https://babeljs.io/repl/)!
On production everyone's using Babel anyway. That would be fine, because on production everyone's using Babel anyway.
Once again, let's note that the most up-to-date situation with support is reflected on [](https://kangax.github.io/compat-table/es6/). Once again, let's note that the most up-to-date situation with support is reflected on [](https://kangax.github.io/compat-table/es6/).
Now we can go coding, but we need a good code editor for that, right? That is discussed in the next session. Now we can go coding, but we need a good code editor for that. That is discussed in the next session.

View file

@ -2,7 +2,7 @@ JavaScript-code:
```js ```js
//+ demo run //+ demo run
var name = prompt("What is your name?", ""); let name = prompt("What is your name?", "");
alert( name ); alert( name );
``` ```
@ -15,7 +15,9 @@ The full page:
<body> <body>
<script> <script>
var name = prompt("What is your name?", ""); 'use strict';
let name = prompt("What is your name?", "");
alert( name ); alert( name );
</script> </script>

View file

@ -45,7 +45,7 @@ As with `alert`, the `prompt` window is modal.
```js ```js
//+ run //+ run
var age = prompt('How old are you?', 100); let age = prompt('How old are you?', 100);
alert(`You are ${age} years old!`) alert(`You are ${age} years old!`)
``` ```
@ -57,14 +57,14 @@ Run this code in Internet Explorer to see that:
```js ```js
//+ run //+ run
var test = prompt("Test"); let test = prompt("Test");
``` ```
So, to look good in IE, it's recommended to always provide the second argument: So, to look good in IE, it's recommended to always provide the second argument:
```js ```js
//+ run //+ run
var test = prompt("Test", ''); // <-- for IE let test = prompt("Test", ''); // <-- for IE
``` ```
[/warn] [/warn]
@ -85,7 +85,7 @@ For example:
```js ```js
//+ run //+ run
var isBoss = confirm("Are you the boss?"); let isBoss = confirm("Are you the boss?");
alert( isBoss ); // true is OK is pressed alert( isBoss ); // true is OK is pressed
``` ```

View file

@ -3,7 +3,9 @@
<body> <body>
<script> <script>
var value = prompt('What is the "official" name of JavaScript?', ''); 'use strict';
let value = prompt('What is the "official" name of JavaScript?', '');
if (value == 'EcmaScript') { if (value == 'EcmaScript') {
alert('Right!'); alert('Right!');

View file

@ -4,7 +4,9 @@
<body> <body>
<script> <script>
var value = prompt('Type a number', 0); 'use strict';
let value = prompt('Type a number', 0);
if (value > 0) { if (value > 0) {
alert(1); alert(1);

View file

@ -2,7 +2,7 @@
```js ```js
//+ run //+ run
var value = prompt('Type a number', 0); let value = prompt('Type a number', 0);
if (value > 0) { if (value > 0) {
alert( 1 ); alert( 1 );

View file

@ -2,11 +2,11 @@
```js ```js
//+ run demo //+ run demo
var userName = prompt('Who's there?', ''); let userName = prompt('Who's there?', '');
if (userName == 'Admin') { if (userName == 'Admin') {
var pass = prompt('Password?', ''); let pass = prompt('Password?', '');
if (pass == 'TheMaster') { if (pass == 'TheMaster') {
alert( 'Welcome!' ); alert( 'Welcome!' );

View file

@ -1,7 +1,7 @@
```js ```js
var message = (login == 'Employee') ? 'Hello' : let message = (login == 'Employee') ? 'Hello' :
(login == 'Director') ? 'Greetings' : (login == 'Director') ? 'Greetings' :
(login == '') ? 'No login' : (login == '') ? 'No login' :
''; '';

View file

@ -7,7 +7,7 @@ Rewrite `if..else` using multiple ternary operators `'?'`.
For readability, please let the code span several lines. For readability, please let the code span several lines.
```js ```js
var message; let message;
if (login == 'Employee') { if (login == 'Employee') {
message = 'Hello'; message = 'Hello';

View file

@ -12,7 +12,7 @@ For example:
```js ```js
//+ run //+ run
var year = prompt('In which year was ECMAScript-2015 specification published?', ''); let year = prompt('In which year was ECMAScript-2015 specification published?', '');
*!* *!*
if (year == 2015) alert( 'You are right!' ); if (year == 2015) alert( 'You are right!' );
@ -63,7 +63,7 @@ if (1) { // 1 is truthy
We can also pass a pre-evaluated logical value to `if`. For example, in a variable like here: We can also pass a pre-evaluated logical value to `if`. For example, in a variable like here:
```js ```js
var cond = (year == 2015); // equality evaluates to true or false let cond = (year == 2015); // equality evaluates to true or false
if (cond) { if (cond) {
... ...
@ -77,7 +77,7 @@ The `if` operator may contain an optional "else" block. It executes when the con
For example: For example:
```js ```js
//+ run //+ run
var year = prompt('In which year was ECMAScript-2015 specification published?', ''); let year = prompt('In which year was ECMAScript-2015 specification published?', '');
if (year == 2015) { if (year == 2015) {
alert( 'You guessed it right!' ); alert( 'You guessed it right!' );
@ -94,7 +94,7 @@ For example:
```js ```js
//+ run //+ run
var year = prompt('In which year was ECMAScript-2015 specification published?', ''); let year = prompt('In which year was ECMAScript-2015 specification published?', '');
if (year < 2015) { if (year < 2015) {
alert( 'Too early...' ); alert( 'Too early...' );
@ -116,8 +116,8 @@ For instance:
```js ```js
//+ run no-beautify //+ run no-beautify
var hasAccess; let hasAccess;
var age = prompt('How old are you?', ''); let age = prompt('How old are you?', '');
*!* *!*
if (age > 14) { if (age > 14) {
@ -136,7 +136,7 @@ The operator is represented by a question mark `"?"`. The formal term "ternary"
The syntax is: The syntax is:
``` ```
var result = condition ? value1 : value2 let result = condition ? value1 : value2
``` ```
The `condition` is evaluated, if it's truthy then `value1` is returned, otherwise -- `value2`. The `condition` is evaluated, if it's truthy then `value1` is returned, otherwise -- `value2`.
@ -144,14 +144,14 @@ The `condition` is evaluated, if it's truthy then `value1` is returned, otherwis
For example: For example:
```js ```js
var hasAccess = (age > 14) ? true : false; let hasAccess = (age > 14) ? true : false;
``` ```
We can omit brackets around `age > 14`, because the question mark operator has a low precedence. It executes after comparisons, so: We can omit brackets around `age > 14`, because the question mark operator has a low precedence. It executes after comparisons, so:
```js ```js
// the same // the same
var hasAccess = age > 14 ? true : false; let hasAccess = age > 14 ? true : false;
``` ```
...But brackets make the code more readable. So it's recommended to put them. ...But brackets make the code more readable. So it's recommended to put them.
@ -161,7 +161,7 @@ In the described case it is possible to evade the question mark operator, becaus
```js ```js
// the same // the same
var hasAccess = age > 14; let hasAccess = age > 14;
``` ```
[/smart] [/smart]
@ -173,9 +173,9 @@ A sequence of question mark `"?"` operators allows to return a value depending o
For instance: For instance:
```js ```js
//+ run //+ run
var age = prompt('age?', 18); let age = prompt('age?', 18);
var message = (age < 3) ? 'Hi, baby!' : let message = (age < 3) ? 'Hi, baby!' :
(age < 18) ? 'Hello!' : (age < 18) ? 'Hello!' :
(age < 100) ? 'Greetings!' : (age < 100) ? 'Greetings!' :
'What an unusual age!'; 'What an unusual age!';
@ -207,7 +207,7 @@ Sometimes the question mark `'?'` is used as a replacement for `if`:
```js ```js
//+ run no-beautify //+ run no-beautify
var company = prompt('Which company created JavaScript?', ''); let company = prompt('Which company created JavaScript?', '');
*!* *!*
(company == 'Netscape') ? (company == 'Netscape') ?
@ -227,7 +227,7 @@ Here's the same with `if` for comparison:
```js ```js
//+ run no-beautify //+ run no-beautify
var company = prompt('Which company created JavaScript?', ''); let company = prompt('Which company created JavaScript?', '');
*!* *!*
if (company == 'Netscape') { if (company == 'Netscape') {

View file

@ -49,7 +49,7 @@ For example:
```js ```js
//+ run //+ run
var hour = 9; let hour = 9;
*!* *!*
if (hour < 10 || hour > 18) { if (hour < 10 || hour > 18) {
@ -62,8 +62,8 @@ We can pass more conditions:
```js ```js
//+ run //+ run
var hour = 12; let hour = 12;
var isWeekend = true; let isWeekend = true;
if (hour < 10 || hour > 18 || isWeekend) { if (hour < 10 || hour > 18 || isWeekend) {
alert( 'The office is closed.' ); // it is weekend alert( 'The office is closed.' ); // it is weekend
@ -112,11 +112,11 @@ Using OR for that:
```js ```js
//+ run //+ run
var currentUser = null; let currentUser = null;
var defaultUser = "John"; let defaultUser = "John";
*!* *!*
var name = currentUser || defaultUser || "unnamed"; let name = currentUser || defaultUser || "unnamed";
*/!* */!*
alert( name ); // outputs "John" -- the first truthy value alert( name ); // outputs "John" -- the first truthy value
@ -134,7 +134,7 @@ If we run the example below, `x` will not get assigned:
```js ```js
//+ run no-beautify //+ run no-beautify
var x; let x;
*!*true*/!* || (x = 1); *!*true*/!* || (x = 1);
@ -145,7 +145,7 @@ alert(x); // undefined, (x = 1) not evaluated
```js ```js
//+ run no-beautify //+ run no-beautify
var x; let x;
*!*false*/!* || (x = 1); *!*false*/!* || (x = 1);
@ -177,7 +177,7 @@ An example with `if`:
```js ```js
//+ run //+ run
var hour = 12, let hour = 12,
minute = 30; minute = 30;
if (hour == 12 && minute == 30) { if (hour == 12 && minute == 30) {
@ -251,7 +251,7 @@ For instance:
```js ```js
//+ run //+ run
var x = 1; let x = 1;
(x > 0) && alert( 'Greater than zero!' ); (x > 0) && alert( 'Greater than zero!' );
``` ```
@ -262,7 +262,7 @@ So we basically have an analogue for:
```js ```js
//+ run //+ run
var x = 1; let x = 1;
if (x > 0) { if (x > 0) {
alert( 'Greater than zero!' ); alert( 'Greater than zero!' );
@ -279,7 +279,7 @@ The boolean NOT operator is represented with an exclamation `"!"`.
The syntax is one of the simplest: The syntax is one of the simplest:
```js ```js
var result = !value; let result = !value;
``` ```
The operator accepts a single argument and does the following: The operator accepts a single argument and does the following:

View file

@ -2,7 +2,7 @@ The answer: `1`.
```js ```js
//+ run //+ run
var i = 3; let i = 3;
while (i) { while (i) {
alert( i-- ); alert( i-- );
@ -14,7 +14,7 @@ Every loop iteration decreases `i` by `1`. The check `while(i)` stops the loop w
Hence, the steps of the loop make the following sequence ("unrolled"): Hence, the steps of the loop make the following sequence ("unrolled"):
```js ```js
var i = 3; let i = 3;
alert(i--); // shows 3, decreases i to 2 alert(i--); // shows 3, decreases i to 2

View file

@ -5,7 +5,7 @@
What is be the last value alerted by this code? Why? What is be the last value alerted by this code? Why?
```js ```js
var i = 3; let i = 3;
while (i) { while (i) {
alert( i-- ); alert( i-- );

View file

@ -5,7 +5,7 @@ The task demonstrates how postfix/prefix forms can lead to different results whe
```js ```js
//+ run //+ run
var i = 0; let i = 0;
while (++i < 5) alert( i ); while (++i < 5) alert( i );
``` ```
@ -19,7 +19,7 @@ Finally, `i=4` is incremented to `5`, the comparison `while(5 < 5)` fails and th
```js ```js
//+ run //+ run
var i = 0; let i = 0;
while (i++ < 5) alert( i ); while (i++ < 5) alert( i );
``` ```

View file

@ -10,7 +10,7 @@ And then compare with the answer.
<li>The prefix form `++i`: <li>The prefix form `++i`:
```js ```js
var i = 0; let i = 0;
while (++i < 5) alert( i ); while (++i < 5) alert( i );
``` ```
@ -18,7 +18,7 @@ while (++i < 5) alert( i );
<li>The postfix form `i++` <li>The postfix form `i++`
```js ```js
var i = 0; let i = 0;
while (i++ < 5) alert( i ); while (i++ < 5) alert( i );
``` ```

View file

@ -2,9 +2,9 @@
```js ```js
//+ run //+ run
for (var i = 0; i < 5; ++i) alert( i ); for (let i = 0; i < 5; ++i) alert( i );
for (var i = 0; i < 5; i++) alert( i ); for (let i = 0; i < 5; i++) alert( i );
``` ```
That can be easily deducted from the algorithm of `for`: That can be easily deducted from the algorithm of `for`:

View file

@ -10,14 +10,14 @@ Then compare with the answer.
<li>The postfix form: <li>The postfix form:
```js ```js
for (var i = 0; i < 5; i++) alert( i ); for (let i = 0; i < 5; i++) alert( i );
``` ```
</li> </li>
<li>The prefix form: <li>The prefix form:
```js ```js
for (var i = 0; i < 5; ++i) alert( i ); for (let i = 0; i < 5; ++i) alert( i );
``` ```
</li> </li>

View file

@ -2,7 +2,7 @@
```js ```js
//+ run demo //+ run demo
for (var i = 2; i <= 10; i++) { for (let i = 2; i <= 10; i++) {
if (i % 2 == 0) { if (i % 2 == 0) {
alert( i ); alert( i );
} }

View file

@ -2,7 +2,7 @@
```js ```js
//+ run //+ run
var i = 0; let i = 0;
while (i < 3) { while (i < 3) {
alert( `number ${i}!` ); alert( `number ${i}!` );
i++; i++;

View file

@ -6,7 +6,7 @@ Rewrite the code changing the `for` loop to `while` without altering it's behavi
```js ```js
//+ run //+ run
for (var i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
alert( `number ${i}!` ); alert( `number ${i}!` );
} }
``` ```

View file

@ -1,7 +1,7 @@
```js ```js
//+ run demo //+ run demo
var num; let num;
do { do {
num = prompt("Enter a number greater than 100?", 0); num = prompt("Enter a number greater than 100?", 0);

View file

@ -15,9 +15,9 @@ The code using a label:
```js ```js
//+ run //+ run
nextPrime: nextPrime:
for (var i = 2; i < 10; i++) { // for each i... for (let i = 2; i < 10; i++) { // for each i...
for (var j = 2; j < i; j++) { // look for a divisor.. for (let j = 2; j < i; j++) { // look for a divisor..
if (i % j == 0) continue nextPrime; // not a prime, go next i if (i % j == 0) continue nextPrime; // not a prime, go next i
} }

View file

@ -23,7 +23,7 @@ For instance, the loop below outputs `i` while `i<3`:
```js ```js
//+ run //+ run
var i = 0; let i = 0;
while (i < 3) { while (i < 3) {
alert( i ); alert( i );
i++; i++;
@ -38,7 +38,7 @@ The `condition` is treated as a logical value, so instead of `while (i!=0)` we u
```js ```js
//+ run //+ run
var i = 3; let i = 3;
*!* *!*
while (i) { // when i becomes 0, the condition is falsy and the loop stops while (i) { // when i becomes 0, the condition is falsy and the loop stops
*/!* */!*
@ -53,7 +53,7 @@ If the loop body has a single statement, we can omit the brackets `{…}`:
```js ```js
//+ run //+ run
var i = 3; let i = 3;
*!* *!*
while (i) alert(i--); while (i) alert(i--);
*/!* */!*
@ -76,7 +76,7 @@ For example:
```js ```js
//+ run //+ run
var i = 0; let i = 0;
do { do {
alert( i ); alert( i );
i++; i++;
@ -101,7 +101,7 @@ An example of the loop which runs `alert(i)` for `i` from `0` to `3` not includi
```js ```js
//+ run //+ run
var i; let i;
for (i = 0; i < 3; i++) { // shows 0, then 1, then 2 for (i = 0; i < 3; i++) { // shows 0, then 1, then 2
alert( i ); alert( i );
@ -133,7 +133,7 @@ We can declare a "counter" variable right in the beginning of the loop.
```js ```js
//+ run no-beautify //+ run no-beautify
for (*!*var*/!* i = 0; i < 3; i++) { for (*!*let*/!* i = 0; i < 3; i++) {
alert(i); // 0, 1, 2 alert(i); // 0, 1, 2
} }
``` ```
@ -148,20 +148,20 @@ For example, we can remove `begin`, or move it before the actual `for`, like her
```js ```js
//+ run //+ run
var i = 0; let i = 0;
for (; i < 3; i++) { for (; i < 3; i++) {
alert( i ); // 0, 1, 2 alert( i ); // 0, 1, 2
} }
``` ```
It would work same as `for(var i=0; ...)`. It would work same as `for(let i=0; ...)`.
We can also remove the `step` part: We can also remove the `step` part:
```js ```js
//+ run //+ run
var i = 0; let i = 0;
for (; i < 3;) { for (; i < 3;) {
alert( i ); alert( i );
@ -195,11 +195,11 @@ But we can force the exit any moment. There's a special `break` directive for th
For example, this code calculates the sum of numbers until the user keeps entering them. And then outputs it: For example, this code calculates the sum of numbers until the user keeps entering them. And then outputs it:
```js ```js
var sum = 0; let sum = 0;
while (true) { while (true) {
var value = +prompt("Enter a number", ''); let value = +prompt("Enter a number", '');
*!* *!*
if (!value) break; // (*) if (!value) break; // (*)
@ -225,7 +225,7 @@ The loop above uses `continue` to output only odd values:
```js ```js
//+ run no-beautify //+ run no-beautify
for (var i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
*!*if (i % 2 == 0) continue;*/!* *!*if (i % 2 == 0) continue;*/!*
@ -239,7 +239,7 @@ For even `i` the `continue` directive stops body execution, passing the control
A loop for odd-only values could look like this: A loop for odd-only values could look like this:
```js ```js
for (var i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
if (i % 2) { if (i % 2) {
alert( i ); alert( i );
@ -295,11 +295,11 @@ For example, in the code below we loop over `i` and `j` asking for values on coo
```js ```js
//+ run no-beautify //+ run no-beautify
for (var i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) { for (let j = 0; j < 3; j++) {
var input = prompt(`Value at coords (${i},${j})`, ''); let input = prompt(`Value at coords (${i},${j})`, '');
// do something with the value... // do something with the value...
} }
@ -325,11 +325,11 @@ Like here:
```js ```js
//+ run no-beautify //+ run no-beautify
*!*outer:*/!* for (var i = 0; i < 3; i++) { *!*outer:*/!* for (let i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) { for (let j = 0; j < 3; j++) {
var input = prompt(`Value at coords (${i},${j})`, ''); let input = prompt(`Value at coords (${i},${j})`, '');
// if an empty string or canceled, then break out of both loops // if an empty string or canceled, then break out of both loops
if (!input) *!*break outer*/!*; // (*) if (!input) *!*break outer*/!*; // (*)
@ -349,7 +349,7 @@ We can also move a label into the separate string:
```js ```js
//+ no-beautify //+ no-beautify
outer: outer:
for (var i = 0; i < 3; i++) { ... } for (let i = 0; i < 3; i++) { ... }
``` ```
The `continue` directive can also be used with a label. In this case the execution would jump onto the next iteration of the labelled loop. The `continue` directive can also be used with a label. In this case the execution would jump onto the next iteration of the labelled loop.

View file

@ -2,7 +2,7 @@ The first two checks are a usual `case`. The third one is split into two cases:
```js ```js
//+ run //+ run
var a = +prompt('a?', ''); let a = +prompt('a?', '');
switch (a) { switch (a) {
case 0: case 0:

View file

@ -6,7 +6,7 @@ Rewrite the code below using a single `switch` statement:
```js ```js
//+ run //+ run
var a = +prompt('a?', ''); let a = +prompt('a?', '');
if (a == 0) { if (a == 0) {
alert( 0 ); alert( 0 );

View file

@ -40,7 +40,7 @@ An example of `switch` (the executed code is highlighted):
```js ```js
//+ run //+ run
var a = 2 + 2; let a = 2 + 2;
switch (a) { switch (a) {
case 3: case 3:
@ -69,7 +69,7 @@ An example without `break`:
```js ```js
//+ run //+ run
var a = 2 + 2; let a = 2 + 2;
switch (a) { switch (a) {
case 3: case 3:
@ -100,8 +100,8 @@ For example:
```js ```js
//+ run //+ run
var a = "1"; let a = "1";
var b = 0; let b = 0;
switch (+a) { switch (+a) {
*!* *!*
@ -125,7 +125,7 @@ For example, if we want the same code for `case 3` and `case 5`:
```js ```js
//+ run no-beautify //+ run no-beautify
var a = 2 + 2; let a = 2 + 2;
switch (a) { switch (a) {
case 4: case 4:
@ -156,7 +156,7 @@ For example, let's consider the code:
```js ```js
//+ run //+ run
var arg = prompt("Enter a value?") let arg = prompt("Enter a value?")
switch (arg) { switch (arg) {
case '0': case '0':
case '1': case '1':

View file

@ -11,17 +11,17 @@
* @return {number} x в степени n * @return {number} x в степени n
*/ */
function pow(x, n) { function pow(x, n) {
var result = x; let result = x;
for (var i = 1; i < n; i++) { for let i = 1; i < n; i++) {
result *= x; result *= x;
} }
return result; return result;
} }
var x = prompt("x?", ''); let x = prompt("x?", '');
var n = prompt("n?", ''); let n = prompt("n?", '');
if (n <= 1) { if (n <= 1) {
alert('Степень ' + n + alert('Степень ' + n +

View file

@ -56,7 +56,7 @@ For example:
//+ run //+ run
function showMessage() { function showMessage() {
*!* *!*
var message = "Hello, I'm JavaScript!"; // local variable let message = "Hello, I'm JavaScript!"; // local variable
*/!* */!*
alert( message ); alert( message );
@ -73,10 +73,10 @@ A function can access an outer variable as well, for example:
```js ```js
//+ run no-beautify //+ run no-beautify
var *!*userName*/!* = 'John'; let *!*userName*/!* = 'John';
function showMessage() { function showMessage() {
var message = 'Hello, my name is ' + *!*userName*/!*; let message = 'Hello, my name is ' + *!*userName*/!*;
alert(message); alert(message);
} }
@ -89,12 +89,12 @@ For instance:
```js ```js
//+ run //+ run
var *!*userName*/!* = 'John'; let *!*userName*/!* = 'John';
function showMessage() { function showMessage() {
userName = "Bob"; // (1) changed the outer variable userName = "Bob"; // (1) changed the outer variable
var message = 'Hello, my name is ' + *!*userName*/!*; let message = 'Hello, my name is ' + *!*userName*/!*;
alert(message); alert(message);
} }
@ -107,18 +107,18 @@ alert( userName ); // Bob, the value was modified by the function
*/!* */!*
``` ```
Of course if we had `var userName = ...` in the line (1) then the function would have a local variable `userName` and use it instead of the outer one: Of course if we had `let userName = ...` in the line (1) then the function would have a local variable `userName` and use it instead of the outer one:
```js ```js
//+ run //+ run
var *!*userName*/!* = 'John'; let *!*userName*/!* = 'John';
function showMessage() { function showMessage() {
*!* *!*
var userName = "Bob"; // declare a local variable let userName = "Bob"; // declare a local variable
*/!* */!*
var message = 'Hello, my name is ' + *!*userName*/!*; let message = 'Hello, my name is ' + *!*userName*/!*;
alert(message); alert(message);
} }
@ -135,7 +135,7 @@ alert( userName ); // John, the outer variable is not modified
Please only declare global the variables which have a project-wide importance. Variables needed by specific tasks should reside in the corresponding functions. So to say, global variables are rare in modern projects. Please only declare global the variables which have a project-wide importance. Variables needed by specific tasks should reside in the corresponding functions. So to say, global variables are rare in modern projects.
[warn header="Attention: implicit global declaration!"] [warn header="Attention: implicit global declaration!"]
In the old JavaScript it was possible to omit variable declaration: Without strict mode, for compatibility with the old scripts, it is possible to omit variable declaration:
```js ```js
//+ run //+ run
@ -148,14 +148,14 @@ showMessage();
alert( message ); // Hello alert( message ); // Hello
``` ```
In the code above `message` was not declared. Most probably, the programmer simply forgot to write `var`. In the code above `message` was not declared. Most probably, the programmer simply forgot to write `let`.
With `"use strict"` there will be an error. But without it, the variable will be created automatically. And not in the function, but globally, in the whole script. With `"use strict"` there will be an error. But without it, the variable will be created automatically. It will be global.
Modern editors and tools for code quality checking like [jshint](http://jshint.com/) allow to see and fix "missed declarations" early while coding. Modern editors and tools for code quality checking like [jshint](http://jshint.com/) allow to see and fix "missed declarations" early while coding.
[/warn] [/warn]
In the future, after we deal with the basics and data structures, in the chapter [](/closures) we will go deeper in the internals of functions and variables. Later, after we deal with the basics and data structures, in the chapter [](/closures) we will go deeper in the internals of functions and variables.
## Параметры ## Параметры
@ -191,7 +191,7 @@ function showMessage(from, text) {
alert( from + ': ' + text ); alert( from + ': ' + text );
} }
var from = "Маша"; let from = "Маша";
showMessage(from, "Привет"); showMessage(from, "Привет");
@ -265,7 +265,7 @@ function calcD(a, b, c) {
*!*return*/!* b*b - 4*a*c; *!*return*/!* b*b - 4*a*c;
} }
var test = calcD(-4, 2, 1); let test = calcD(-4, 2, 1);
alert(test); // 20 alert(test); // 20
``` ```
@ -285,7 +285,7 @@ function checkAge(age) {
} }
} }
var age = prompt('Ваш возраст?'); let age = prompt('Ваш возраст?');
if (checkAge(age)) { if (checkAge(age)) {
alert( 'Доступ разрешен' ); alert( 'Доступ разрешен' );

View file

@ -25,7 +25,7 @@ function sayHi() { // (1)
alert( "Привет" ); alert( "Привет" );
} }
var func = sayHi; // (2) let func = sayHi; // (2)
func(); // Привет // (3) func(); // Привет // (3)
sayHi = null; sayHi = null;
@ -34,7 +34,7 @@ sayHi(); // ошибка (4)
<ol> <ol>
<li>Объявление `(1)` как бы говорит интерпретатору "создай функцию и помести её в переменную `sayHi`</li> <li>Объявление `(1)` как бы говорит интерпретатору "создай функцию и помести её в переменную `sayHi`</li>
<li>В строке `(2)` мы копируем функцию в новую переменную `func`. Ещё раз обратите внимание: после `sayHi` нет скобок. Если бы они были, то вызов `var func = sayHi()` записал бы в `func` *результат* работы `sayHi()` (кстати, чему он равен? правильно, `undefined`, ведь внутри `sayHi` нет `return`).</li> <li>В строке `(2)` мы копируем функцию в новую переменную `func`. Ещё раз обратите внимание: после `sayHi` нет скобок. Если бы они были, то вызов `let func = sayHi()` записал бы в `func` *результат* работы `sayHi()` (кстати, чему он равен? правильно, `undefined`, ведь внутри `sayHi` нет `return`).</li>
<li>На момент `(3)` функцию можно вызывать и как `sayHi()` и как `func()`</li> <li>На момент `(3)` функцию можно вызывать и как `sayHi()` и как `func()`</li>
<li>...Однако, в любой момент значение переменной можно поменять. При этом, если оно не функция, то вызов `(4)` выдаст ошибку.</li> <li>...Однако, в любой момент значение переменной можно поменять. При этом, если оно не функция, то вызов `(4)` выдаст ошибку.</li>
</ol> </ol>
@ -52,7 +52,7 @@ sayHi(); // ошибка (4)
```js ```js
//+ run //+ run
var f = function(параметры) { let f = function(параметры) {
// тело функции // тело функции
}; };
``` ```
@ -61,7 +61,7 @@ var f = function(параметры) {
```js ```js
//+ run //+ run
var sayHi = function(person) { let sayHi = function(person) {
alert( "Привет, " + person ); alert( "Привет, " + person );
}; };
@ -86,7 +86,7 @@ function sum(a, b) {
} }
// Function Expression // Function Expression
var sum = function(a, b) { let sum = function(a, b) {
return a + b; return a + b;
} }
``` ```
@ -116,7 +116,7 @@ function sayHi(name) {
sayHi("Вася"); // ошибка! sayHi("Вася"); // ошибка!
*/!* */!*
var sayHi = function(name) { let sayHi = function(name) {
alert( "Привет, " + name ); alert( "Привет, " + name );
} }
``` ```
@ -137,7 +137,7 @@ var sayHi = function(name) {
```js ```js
//+ run //+ run
var age = +prompt("Сколько вам лет?", 20); let age = +prompt("Сколько вам лет?", 20);
if (age >= 18) { if (age >= 18) {
function sayHi() { function sayHi() {
@ -170,7 +170,7 @@ function sayHi() {
alert( 'До 18 нельзя' ); alert( 'До 18 нельзя' );
} }
var age = 20; let age = 20;
if (age >= 18) { if (age >= 18) {
/* объявление было обработано ранее */ /* объявление было обработано ранее */
@ -195,9 +195,9 @@ sayHi(); // "До 18 нельзя", сработает всегда вторая
```js ```js
//+ run //+ run
var age = prompt('Сколько вам лет?'); let age = prompt('Сколько вам лет?');
var sayHi; let sayHi;
if (age >= 18) { if (age >= 18) {
sayHi = function() { sayHi = function() {
@ -216,9 +216,9 @@ sayHi();
```js ```js
//+ run no-beautify //+ run no-beautify
var age = prompt('Сколько вам лет?'); let age = prompt('Сколько вам лет?');
var sayHi = (age >= 18) ? let sayHi = (age >= 18) ?
function() { alert('Прошу Вас!'); } : function() { alert('Прошу Вас!'); } :
function() { alert('До 18 нельзя'); }; function() { alert('До 18 нельзя'); };
@ -294,9 +294,9 @@ ask(
```js ```js
//+ run //+ run
var sum = new Function('a,b', ' return a+b; '); let sum = new Function('a,b', ' return a+b; ');
var result = sum(1, 2); let result = sum(1, 2);
alert( result ); // 3 alert( result ); // 3
``` ```
@ -346,7 +346,7 @@ alert( result ); // 3
</tr> </tr>
</table> </table>
Иногда в коде начинающих разработчиков можно увидеть много Function Expression. Почему-то, видимо, не очень понимая происходящее, функции решают создавать как `var func = function()`, но в большинстве случаев обычное объявление функции -- лучше. Иногда в коде начинающих разработчиков можно увидеть много Function Expression. Почему-то, видимо, не очень понимая происходящее, функции решают создавать как `let func = function()`, но в большинстве случаев обычное объявление функции -- лучше.
**Если нет явной причины использовать Function Expression -- предпочитайте Function Declaration.** **Если нет явной причины использовать Function Expression -- предпочитайте Function Declaration.**
@ -355,7 +355,7 @@ alert( result ); // 3
```js ```js
//+ no-beautify //+ no-beautify
// Function Expression // Function Expression
var f = function() { ... } let f = function() { ... }
// Function Declaration // Function Declaration
function f() { ... } function f() { ... }

View file

@ -223,7 +223,7 @@ If we'd like to add several `<script>` tags on the page and keep their execution
Like this: Like this:
```js ```js
function addScript(src); function addScript(src);
var script = document.createElement('script'); let script = document.createElement('script');
script.src = src; script.src = src;
*!* *!*
script.async = false; script.async = false;

View file

@ -3,8 +3,8 @@
```js ```js
//+ run //+ run
function sumTo(n) { function sumTo(n) {
var sum = 0; let sum = 0;
for (var i = 1; i <= n; i++) { for let i = 1; i <= n; i++) {
sum += i; sum += i;
} }
return sum; return sum;

View file

@ -37,8 +37,8 @@ fib(4) = fib(3) + fib(2)
```js ```js
//+ no-beautify //+ no-beautify
var a = 1, b = 1; // начальные значения let a = 1, b = 1; // начальные значения
var c = a + b; // 2 let c = a + b; // 2
/* переменные на начальном шаге: /* переменные на начальном шаге:
a b c a b c
@ -81,10 +81,10 @@ P.S. Этот подход к вычислению называется [дин
```js ```js
//+ run //+ run
function fib(n) { function fib(n) {
var a = 1, let a = 1,
b = 1; b = 1;
for (var i = 3; i <= n; i++) { for let i = 3; i <= n; i++) {
var c = a + b; let c = a + b;
a = b; a = b;
b = c; b = c;
} }

View file

@ -193,8 +193,8 @@ function pow(x, n) {
```js ```js
function pow(x, n) { function pow(x, n) {
var result = x; let result = x;
for (var i = 1; i < n; i++) { for let i = 1; i < n; i++) {
result *= x; result *= x;
} }
return result; return result;

View file

@ -9,14 +9,14 @@
Обычное функциональное выражение: Обычное функциональное выражение:
```js ```js
var f = function(...) { /* тело функции */ }; let f = function(...) { /* тело функции */ };
``` ```
Именованное с именем `sayHi`: Именованное с именем `sayHi`:
```js ```js
//+ no-beautify //+ no-beautify
var f = function *!*sayHi*/!*(...) { /* тело функции */ }; let f = function *!*sayHi*/!*(...) { /* тело функции */ };
``` ```
Что же это за имя, которое идёт в дополнение к `f`, и зачем оно? Что же это за имя, которое идёт в дополнение к `f`, и зачем оно?
@ -29,7 +29,7 @@ var f = function *!*sayHi*/!*(...) { /* тело функции */ };
```js ```js
//+ run //+ run
var f = function sayHi(name) { let f = function sayHi(name) {
alert( sayHi ); // изнутри функции - видно (выведет код функции) alert( sayHi ); // изнутри функции - видно (выведет код функции)
}; };
@ -40,7 +40,7 @@ alert( sayHi ); // снаружи - не видно (ошибка: undefined var
```js ```js
//+ run //+ run
var test = function sayHi(name) { let test = function sayHi(name) {
*!* *!*
sayHi = "тест"; // попытка перезаписи sayHi = "тест"; // попытка перезаписи
*/!* */!*
@ -80,7 +80,7 @@ function f(n) {
}; };
*!* *!*
var g = f; let g = f;
f = null; f = null;
*/!* */!*
@ -93,11 +93,11 @@ alert( g(5) ); // запуск функции с новым именем - ош
```js ```js
//+ run no-beautify //+ run no-beautify
var f = function *!*factorial*/!*(n) { let f = function *!*factorial*/!*(n) {
return n ? n**!*factorial*/!*(n-1) : 1; return n ? n**!*factorial*/!*(n-1) : 1;
}; };
var g = f; // скопировали ссылку на функцию-факториал в g let g = f; // скопировали ссылку на функцию-факториал в g
f = null; f = null;
*!* *!*
@ -115,7 +115,7 @@ alert( g(5) ); // 120, работает!
```js ```js
//+ run //+ run
var f = function factorial(n) { /*...*/ }; let f = function factorial(n) { /*...*/ };
// в IE8- false // в IE8- false
// в остальных браузерах ошибка, т.к. имя factorial не видно // в остальных браузерах ошибка, т.к. имя factorial не видно

View file

@ -29,7 +29,7 @@ alert('Мир')
```js ```js
//+ run no-beautify //+ run no-beautify
var a = 2 let a = 2
+3 +3
alert(a); // 5 alert(a); // 5
@ -55,10 +55,10 @@ alert("После этого сообщения будет ошибка")
## Переменные и типы ## Переменные и типы
<ul> <ul>
<li>Объявляются директивой `var`. Могут хранить любое значение: <li>Объявляются директивой `let`. Могут хранить любое значение:
```js ```js
var x = 5; let x = 5;
x = "Петя"; x = "Петя";
``` ```
@ -85,7 +85,7 @@ x = undefined; // спец. значение (само себе тип)
Например: Например:
```js ```js
var age = null; // возраст неизвестен let age = null; // возраст неизвестен
``` ```
</li> </li>
@ -94,7 +94,7 @@ var age = null; // возраст неизвестен
Например: Например:
```js ```js
var x; let x;
alert( x ); // undefined alert( x ); // undefined
``` ```
@ -119,7 +119,7 @@ alert( x ); // undefined
Эта директива может также указываться в начале функций. При этом функция будет выполняться в режиме соответствия, а на внешний код такая директива не повлияет. Эта директива может также указываться в начале функций. При этом функция будет выполняться в режиме соответствия, а на внешний код такая директива не повлияет.
Одно из важных изменений в современном стандарте -- все переменные нужно объявлять через `var`. Есть и другие, которые мы изучим позже, вместе с соответствующими возможностями языка. Одно из важных изменений в современном стандарте -- все переменные нужно объявлять через `let`. Есть и другие, которые мы изучим позже, вместе с соответствующими возможностями языка.
@ -142,8 +142,8 @@ alert( x ); // undefined
```js ```js
//+ run //+ run
var userName = prompt("Введите имя?", "Василий"); let userName = prompt("Введите имя?", "Василий");
var isTeaWanted = confirm("Вы хотите чаю?"); let isTeaWanted = confirm("Вы хотите чаю?");
alert( "Посетитель: " + userName ); alert( "Посетитель: " + userName );
alert( "Чай: " + isTeaWanted ); alert( "Чай: " + isTeaWanted );
@ -254,7 +254,7 @@ do {
} while (условие); } while (условие);
// 3 // 3
for (var i = 0; i < 10; i++) { for let i = 0; i < 10; i++) {
... ...
} }
``` ```
@ -292,7 +292,7 @@ for(;;) {
```js ```js
//+ run //+ run
var age = prompt('Ваш возраст', 18); let age = prompt('Ваш возраст', 18);
switch (age) { switch (age) {
case 18: case 18:
@ -317,7 +317,7 @@ switch (age) {
//+ run //+ run
// function имя(список параметров) { тело } // function имя(список параметров) { тело }
function sum(a, b) { function sum(a, b) {
var result = a + b; let result = a + b;
return result; return result;
} }
@ -328,7 +328,7 @@ alert( sum(1, 2) ); // 3
<ul> <ul>
<li>`sum` -- имя функции, ограничения на имя функции -- те же, что и на имя переменной.</li> <li>`sum` -- имя функции, ограничения на имя функции -- те же, что и на имя переменной.</li>
<li>Переменные, объявленные через `var` внутри функции, видны везде внутри этой функции, блоки `if`, `for` и т.п. на видимость не влияют.</li> <li>Переменные, объявленные через `let` внутри функции, видны везде внутри этой функции, блоки `if`, `for` и т.п. на видимость не влияют.</li>
<li>Параметры копируются в локальные переменные `a`, `b`. <li>Параметры копируются в локальные переменные `a`, `b`.
</li> </li>
<li>Функция без `return` считается возвращающей `undefined`. Вызов `return` без значения также возвращает `undefined`: <li>Функция без `return` считается возвращающей `undefined`. Вызов `return` без значения также возвращает `undefined`:
@ -352,8 +352,8 @@ alert( f() ); // undefined
```js ```js
//+ run //+ run
var sum = function(a, b) { let sum = function(a, b) {
var result = a + b; let result = a + b;
return result; return result;
} }
@ -371,7 +371,7 @@ alert( sum(1, 2) ); // 3
## Named Function Expression ## Named Function Expression
Если объявление функции является частью какого-либо выражения, например `var f = function...` или любого другого, то это Function Expression. Если объявление функции является частью какого-либо выражения, например `let f = function...` или любого другого, то это Function Expression.
В этом случае функции можно присвоить "внутреннее" имя, указав его после `function`. Оно будет видно только внутри этой функции и позволяет обратиться к функции изнутри себя. Обычно это используется для рекурсивных вызовов. В этом случае функции можно присвоить "внутреннее" имя, указав его после `function`. Оно будет видно только внутри этой функции и позволяет обратиться к функции изнутри себя. Обычно это используется для рекурсивных вызовов.
@ -379,7 +379,7 @@ alert( sum(1, 2) ); // 3
```js ```js
//+ run //+ run
var factorial = function me(n) { let factorial = function me(n) {
return (n == 1) ? n : n * me(n - 1); return (n == 1) ? n : n * me(n - 1);
} }

View file

@ -2,7 +2,7 @@ In the code below, each line corresponds to the item in the task list.
```js ```js
//+ run //+ run
var admin, name; // can declare two variables at once let admin, name; // can declare two variables at once
name = "John"; name = "John";

View file

@ -3,7 +3,7 @@ First, the variable for the name of our planet.
That's simple: That's simple:
```js ```js
var ourPlanetName = "Earth"; let ourPlanetName = "Earth";
``` ```
Note, we could use a shorter name `planet`, but it might be not obvious what planet it refers to. It's nice to be more verbose. At least until the variable isNotTooLong. Note, we could use a shorter name `planet`, but it might be not obvious what planet it refers to. It's nice to be more verbose. At least until the variable isNotTooLong.
@ -11,7 +11,7 @@ Note, we could use a shorter name `planet`, but it might be not obvious what pla
Second, the name of the current visitor: Second, the name of the current visitor:
```js ```js
var currentUserName = "John"; let currentUserName = "John";
``` ```
Again, we could shorten that to `userName` if we know beyound the reasonable doubt that the user is current. Again, we could shorten that to `userName` if we know beyound the reasonable doubt that the user is current.

View file

@ -2,7 +2,7 @@
Depending on our aims, the script needs to work with the information. Depending on our aims, the script needs to work with the information.
If it's an online-shop -- that's going to be the goods and the card. If it's a chat -- visitors, message and so on. If it's an online-shop -- that's going to be the goods and the card. If it's a chat -- visitors, messages and so on.
Variables are used to store the information. Variables are used to store the information.
@ -10,35 +10,31 @@ Variables are used to store the information.
## A variable ## A variable
According to Wikipedia, a [variable]("https://en.wikipedia.org/wiki/Variable_(computer_science)") is a storage location paired with an associated symbolic name (identifier). The name is used to access the stored information. A [variable]("https://en.wikipedia.org/wiki/Variable_(computer_science)") is a "named storage" for the information.
To declare a variable in JavaScript, there are two keywords: To declare a variable in JavaScript, we need to use the `let` keyword.
<ol> The statement below creates (in other words: *declares* or *defines*) the variable with the name "message":
<li>the `var` keyword comes from the ancient times.</li>
<li>the `let` keyword is a "modern school".</li>
</ol>
We'll start with `var`, because it is widely used in older scripts and we need to understand it. Later when we know enough to understand the subtle differences (when they actually matter for us) we'll move further to `let`.
The statement below creates (in other words: *declares* or *defines*) the variable `message`:
```js ```js
var message; let message;
``` ```
Now we can assign some data into it: Now we can assign some data into it:
```js ```js
var message; let message;
message = 'Hello'; // keep the string
*!*
message = 'Hello'; // store the string
*/!*
``` ```
The string is now saved into the associated memory area. We can access it using the variable name: The string is now saved into the associated memory area. We can access it using the variable name:
```js ```js
//+ run //+ run
var message; let message;
message = 'Hello!'; message = 'Hello!';
alert( message ); // shows the variable content alert( message ); // shows the variable content
@ -47,14 +43,14 @@ alert( message ); // shows the variable content
To be concise we can merge the variable declaration and assignment into a single line: To be concise we can merge the variable declaration and assignment into a single line:
```js ```js
var message = 'Hello!'; let message = 'Hello!';
``` ```
We can also declare multiple variables in one line: We can also declare multiple variables in one line:
```js ```js
//+ no-beautify //+ no-beautify
var user = 'John', age = 25, message = 'Hello'; let user = 'John', age = 25, message = 'Hello';
``` ```
That might seem shorter, but it's recommended, for the sake of beter readability, to use a single line per variable. That might seem shorter, but it's recommended, for the sake of beter readability, to use a single line per variable.
@ -63,16 +59,28 @@ This code is a bit longer, but easier to read:
```js ```js
//+ no-beautify //+ no-beautify
var user = 'John'; let user = 'John';
var age = 25; let age = 25;
var message = 'Hello'; let message = 'Hello';
``` ```
[smart header="`var` instead of `let`"]
In older scripts you may also find another keyword: `var` instead of `let`:
```js
*!*var*/!* message = 'Hello';
```
The `var` keyword is *almost* the same as `let`. It also declares a variable, but in a slightly different, "old-school" fashion.
The subtle differences does not matter yet, but we'll cover them in detail later when going deeper into the language.
[/smart]
## Real-life analogy ## Real-life analogy
We can easily grasp the concept of a "variable" if we imagine it as a "box" for the data, with the unique-named sticker on it. We can easily grasp the concept of a "variable" if we imagine it as a "box" for the data, with the unique-named sticker on it.
For instance, the variable `message` -- is a box with the value `"Hello!" labelled `"message"`: For instance, the variable `message` is a box with the value `"Hello!" labelled `"message"`:
<img src="variable.png"> <img src="variable.png">
@ -82,7 +90,7 @@ The value can be changed as many times as we need:
```js ```js
//+ run //+ run
var message; let message;
message = 'Hello!'; message = 'Hello!';
@ -99,9 +107,9 @@ We can also declare two variables and copy data from one into another.
```js ```js
//+ run //+ run
var hello = 'Hello world!'; let hello = 'Hello world!';
var message; let message;
*!* *!*
// copy value // copy value
@ -134,8 +142,8 @@ There are two limitations on the variable name in JavaScript:
Valid name examples: Valid name examples:
```js ```js
var userName; let userName;
var test123; let test123;
``` ```
When the name contains multiple words, [camelCase](https://en.wikipedia.org/wiki/CamelCase) is commonly used. That is: words go one after another with the capital letter at start: `myVeryLongName`. When the name contains multiple words, [camelCase](https://en.wikipedia.org/wiki/CamelCase) is commonly used. That is: words go one after another with the capital letter at start: `myVeryLongName`.
@ -146,8 +154,8 @@ These names are valid:
```js ```js
//+ run untrusted //+ run untrusted
var $ = 1; // declared a variable with the name "$" let $ = 1; // declared a variable with the name "$"
var _ = 2; // and now the variable with the name "_" let _ = 2; // and now the variable with the name "_"
alert( $ + _ ); // 3 alert( $ + _ ); // 3
``` ```
@ -156,9 +164,9 @@ Examples of incorrect variable names:
```js ```js
//+ no-beautify //+ no-beautify
var 1a; // cannot start with a digit let 1a; // cannot start with a digit
var my-name; // a hyphen '-' is not allowed in the name let my-name; // a hyphen '-' is not allowed in the name
``` ```
[smart header="Case matters"] [smart header="Case matters"]
@ -171,8 +179,8 @@ It is possible to use cyrillic letters or even hieroglyphs, like this:
```js ```js
//+ run //+ run
var имя = 123; let имя = 123;
var 我 = 456; let 我 = 456;
``` ```
Technically, there is no error here, but there is a tradition to use only latin alphabet in variable names. Technically, there is no error here, but there is a tradition to use only latin alphabet in variable names.
@ -187,28 +195,28 @@ The code below will give a syntax error:
```js ```js
//+ run no-beautify //+ run no-beautify
var return = 5; // error! let return = 5; // error!
``` ```
[/warn] [/warn]
## Strict mode and "var" ## Non-Strict mode assignment
Without strict mode, it is possible to create a variable without a `var`, by a mere assignment of the value: Without strict mode, it is possible to create a variable without a `let`, by a mere assignment of the value:
```js ```js
//+ run //+ run no-strict
num = 5; // the variable "num" is created if didn't exist num = 5; // the variable "num" is created if didn't exist
alert(num); alert(num);
``` ```
...But in `"use strict"` it is not allowed. ...But that is allowed for compatibility with the old scripts. It is a frowned-upon feature that is disabled in the strict mode.
The code below will give an error: The code below will give an error:
```js ```js
//+ run //+ run untrusted
"use strict"; "use strict";
*!* *!*
@ -222,17 +230,26 @@ Please make sure that `"use strict"` is on the top of the script, otherwise the
There is no strict mode here: There is no strict mode here:
```js ```js
//+ run //+ run untrusted no-strict
var something; alert("some code");
// …
"use strict"; // too late "use strict"; // ignored, because not on top
*!* *!*
num = 5; // no error, strict mode is not activated num = 5; // No error! strict mode is not activated
*/!* */!*
``` ```
[/smart] [/smart]
## Chrome (V8) needs "use strict" for "let"
In Chrome browser and Node.JS, both powered by V8 engine, `"use strict"` is required if we want to use `let` and many other modern features of the language.
Here, on-site, most examples are evaluated with implicit (omitted in text, but auto-added before execution) `"use strict"`.
But when you write JS, make sure that you do not forget `"use strict". Otherwise using `let` will give you an error in console.
## Constants ## Constants
Variables with a fixed value are called "constant variables" or just *constants*. Variables with a fixed value are called "constant variables" or just *constants*.
@ -241,28 +258,12 @@ To declare a constant variable, one can use `const`:
```js ```js
//+ run //+ run
'use strict';
const myBirthday = '18.04.1982'; const myBirthday = '18.04.1982';
color = '01.01.2001'; // error! myBirthday = '01.01.2001'; // error!
```
The code below can now calculate other values based on the constant, like the age or the sign of the zodiac. It can be sure that the calculations are always valid, because `myBirthday` never changes.
Please note that `const` variables actually *can be assigned*, but only once.
This is not an error:
```js
//+ run
'use strict';
const myBirthday;
myBirthday = '18.04.1982'; // the first assignment
``` ```
A constant variable never changes, so the further code can rely on that to calculate dependant values (like the age or the sign of the zodiac). It can be sure that the calculations are always valid.
[smart header="CONSTANT_NAMING"] [smart header="CONSTANT_NAMING"]
There is a widespread practice to use constants as aliases for difficult-to-remember values. Such constants are named using capitals and underscores. There is a widespread practice to use constants as aliases for difficult-to-remember values. Such constants are named using capitals and underscores.
@ -276,10 +277,7 @@ const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F"; const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00"; const COLOR_ORANGE = "#FF7F00";
const a; let color = COLOR_ORANGE;
a = 5;
var color = COLOR_ORANGE;
alert( color ); // #FF7F00 alert( color ); // #FF7F00
``` ```
@ -292,13 +290,13 @@ So, sometimes constants are used as aliases to complex values, to evade errors a
## Summary ## Summary
<ul> We can declare variables to store data. That can be done using `var` or `let` or `const`.
<li>We must declare variables to store data. That can be done using `var` or `let`. As of now we can think that `let` is a newer alias of `var`, later we'll cover their differences in detail.</li>
<li>We can assign a value when the variable is declared: `var x = 10`.</li>
<li>If a variable is not going to change after assignment, it is called "a constant". We can use `const` keyword instead of `var` to declare constants.</li>
</ul>
And there's one more thing. The most important one. <ul>
<li>`let` -- is a normal modern variable declaration. The code must be in strict mode to use in Chrome (V8).</li>
<li>`var` -- is an old-school compatibility variable declaration. We'll study the subtle differences from `let` later, after we get familiar with the basics.</li>
<li>`const` -- is like `let`, but the variable can't be changed.</li>
</ul>
Please name the variables sensibly. Please name the variables sensibly.

View file

@ -9,7 +9,7 @@ Here we will get the common understanding of them. In the next chapters we'll ta
## A number ## A number
```js ```js
var n = 123; let n = 123;
n = 12.345; n = 12.345;
``` ```
@ -41,9 +41,9 @@ We'll cover working with numbers in the chapter [](/number).
## A string ## A string
```js ```js
var str = "Hello"; let str = "Hello";
var str2 = 'Single quotes are ok too'; let str2 = 'Single quotes are ok too';
var phrase = `can embed ${str}`; let phrase = `can embed ${str}`;
``` ```
In JavaScript, there are 3 types of quotes. In JavaScript, there are 3 types of quotes.
@ -59,15 +59,15 @@ Double and single quotes are essentially the same. The only difference between t
A double quote symbol may appear inside single-quoted lines and vise versa: A double quote symbol may appear inside single-quoted lines and vise versa:
```js ```js
var hello = "I'm JavaScript"; // single-quote inside "…" let hello = "I'm JavaScript"; // single-quote inside "…"
var name = 'My "official" name is "EcmaScript"'; // vise versa let name = 'My "official" name is "EcmaScript"'; // vise versa
``` ```
If we want to include a single quote inside a same-quoted string, we can do it too. But we need to prepend it with a slash: If we want to include a single quote inside a same-quoted string, we can do it too. But we need to prepend it with a slash:
```js ```js
// prepend ' inside the string with a slash \' // prepend ' inside the string with a slash \'
var hello = 'I\'m JavaScript'; let hello = 'I\'m JavaScript';
``` ```
Similarly with double quotes. Similarly with double quotes.
@ -90,7 +90,7 @@ For instance:
```js ```js
//+ no-beautify //+ no-beautify
var checked = true; // the form field is checked let checked = true; // the form field is checked
checked = false; // the form field is not checked checked = false; // the form field is not checked
``` ```
@ -98,7 +98,7 @@ Boolean values usually originate from the comparisons:
```js ```js
//+ run //+ run
var isGreater = 4 > 1; let isGreater = 4 > 1;
alert(isGreater); // true alert(isGreater); // true
``` ```
@ -111,7 +111,7 @@ The special `null` value does not belong to any type described above.
It forms a separate type of its own, which contains only the `null` value: It forms a separate type of its own, which contains only the `null` value:
```js ```js
var age = null; let age = null;
``` ```
In JavaScript `null` is not a "reference to a non-existing object" or a "null pointer" like in some other languages. In JavaScript `null` is not a "reference to a non-existing object" or a "null pointer" like in some other languages.
@ -130,7 +130,7 @@ If a variable is declared, but not assigned, then its value is exactly `undefine
```js ```js
//+ run //+ run
var x; let x;
alert( x ); // shows "undefined" alert( x ); // shows "undefined"
``` ```
@ -138,7 +138,7 @@ Technically, it is possible to assign to `undefined`:
```js ```js
//+ run //+ run
var x = 123; let x = 123;
x = undefined; x = undefined;
alert( x ); // "undefined" alert( x ); // "undefined"
@ -198,7 +198,7 @@ A variable in JavaScript can contain any data. The same variable can get a strin
```js ```js
// perfectly fine // perfectly fine
var message = "hello"; let message = "hello";
message = 123456; message = 123456;
``` ```
@ -222,7 +222,7 @@ For example, `alert` does it:
```js ```js
//+ run //+ run
var a = true; let a = true;
alert( a ); // "true" alert( a ); // "true"
``` ```
@ -231,7 +231,7 @@ We can also use a call `String(value)` function for that:
```js ```js
//+ run //+ run
var a = true; let a = true;
a = String(a); // now: a = "true" a = String(a); // now: a = "true"
alert(typeof a); // string alert(typeof a); // string
@ -254,7 +254,7 @@ Although if we want to ensure that the value is a number, we can use a `Number(v
```js ```js
//+ run //+ run
var n = Number("6"); let n = Number("6");
alert(typeof n); // number alert(typeof n); // number
``` ```
@ -267,7 +267,7 @@ For example:
```js ```js
//+ run //+ run
var age = Number("a user-supplied string"); let age = Number("a user-supplied string");
alert(age); // NaN, conversion failed alert(age); // NaN, conversion failed
alert(age); // number, because NaN belongs to the "number" type alert(age); // number, because NaN belongs to the "number" type
@ -333,7 +333,7 @@ An object is defined with the figure brackets `{…}`.
For instance, here we create a `user` object with the name and the age: For instance, here we create a `user` object with the name and the age:
```js ```js
var user = { let user = {
name: "John", name: "John",
age: 30 age: 30
}; };
@ -353,7 +353,7 @@ We'll cover working with objects in the chapter [](/object).
The `symbol` type is used to create unique identifiers. The `symbol` type is used to create unique identifiers.
```js ```js
var id = Symbol("id"); let id = Symbol("id");
``` ```
...And then we could use `id` as a special kind of identifier for object properties. We'll see more about object properties in the following chapters. ...And then we could use `id` as a special kind of identifier for object properties. We'll see more about object properties in the following chapters.

View file

@ -2,7 +2,7 @@
```js ```js
//+ run no-beautify //+ run no-beautify
var a = 1, b = 1, c, d; let a = 1, b = 1, c, d;
// префиксная форма сначала увеличивает a до 2, а потом возвращает // префиксная форма сначала увеличивает a до 2, а потом возвращает
c = ++a; alert(c); // 2 c = ++a; alert(c); // 2

View file

@ -6,7 +6,7 @@
```js ```js
//+ run no-beautify //+ run no-beautify
var a = 1, b = 1, c, d; let a = 1, b = 1, c, d;
c = ++a; alert(c); // 2 c = ++a; alert(c); // 2
d = b++; alert(d); // 1 d = b++; alert(d); // 1

View file

@ -4,7 +4,7 @@
```js ```js
//+ run //+ run
var a = 2; let a = 2;
alert( a *= 2 ); // 4 alert( a *= 2 ); // 4
``` ```

View file

@ -5,8 +5,8 @@
Чему будет равен `x` в примере ниже? Чему будет равен `x` в примере ниже?
```js ```js
var a = 2; let a = 2;
var x = 1 + (a *= 2); let x = 1 + (a *= 2);
``` ```

View file

@ -15,7 +15,7 @@ Before we move on, let's make a dip in the terminology, to understand what we're
```js ```js
//+ run //+ run
var x = 1; let x = 1;
*!* *!*
x = -x; x = -x;
@ -28,7 +28,7 @@ alert( x ); // -1, unary minus was applied
```js ```js
//+ run no-beautify //+ run no-beautify
var x = 1, y = 3; let x = 1, y = 3;
alert( y - x ); // 2, binary minus alert( y - x ); // 2, binary minus
``` ```
@ -44,7 +44,7 @@ Usually the plus operator `'+'` sums numbers.
But if the binary `+` is applied to strings, it merges (concatenates) them: But if the binary `+` is applied to strings, it merges (concatenates) them:
```js ```js
var s = "my" + "string"; let s = "my" + "string";
alert( s ); // mystring alert( s ); // mystring
``` ```
@ -77,10 +77,10 @@ The unary plus or, in other words, the plus applied to a single value, doesn't d
```js ```js
//+ run //+ run
var x = 1; let x = 1;
alert( +x ); // 1 alert( +x ); // 1
var y = -2; let y = -2;
alert( +y ); // -2 alert( +y ); // -2
``` ```
@ -96,8 +96,8 @@ The binary plus would add them as strings:
```js ```js
//+ run //+ run
var apples = "2"; let apples = "2";
var oranges = "3"; let oranges = "3";
alert( apples + oranges ); // "23", the binary plus concatenates strings alert( apples + oranges ); // "23", the binary plus concatenates strings
``` ```
@ -106,8 +106,8 @@ So we can use the unary plus to convert values to numbers, and then sum them:
```js ```js
//+ run //+ run
var apples = "2"; let apples = "2";
var oranges = "3"; let oranges = "3";
alert( +apples + +oranges ); // 5, both operands converted to numbers before the binary plus alert( +apples + +oranges ); // 5, both operands converted to numbers before the binary plus
``` ```
@ -148,7 +148,7 @@ Let's note that an assignment `=` is also an operator. It is listed in the prece
That's why when we assign a variable, like `x = 2 * 2 + 1`, the maths is done first, and then the assignment is evaluated. That's why when we assign a variable, like `x = 2 * 2 + 1`, the maths is done first, and then the assignment is evaluated.
```js ```js
var x = 2 * 2 + 1; let x = 2 * 2 + 1;
alert( x ); // 5 alert( x ); // 5
``` ```
@ -157,7 +157,7 @@ It is possible to chain assignments:
```js ```js
//+ run //+ run
var a, b, c; let a, b, c;
*!* *!*
a = b = c = 2 + 2; a = b = c = 2 + 2;
@ -179,11 +179,11 @@ So it is actually possible to use an assignment as the part of the more complex
```js ```js
//+ run //+ run
var a = 1; let a = 1;
var b = 2; let b = 2;
*!* *!*
var c = 3 - (a = b + 1); let c = 3 - (a = b + 1);
*/!* */!*
alert( a ); // 3 alert( a ); // 3
@ -223,7 +223,7 @@ So, there are special operators for that:
```js ```js
//+ run no-beautify //+ run no-beautify
var i = 2; let i = 2;
i++; // works same as i = i + 1, but shorter i++; // works same as i = i + 1, but shorter
alert(i); // 3 alert(i); // 3
``` ```
@ -233,7 +233,7 @@ alert(i); // 3
```js ```js
//+ run no-beautify //+ run no-beautify
var i = 2; let i = 2;
i--; // works same as i = i - 1, but shorter i--; // works same as i = i - 1, but shorter
alert(i); // 1 alert(i); // 1
``` ```
@ -261,8 +261,8 @@ Let's see the examples:
```js ```js
//+ run //+ run
var i = 1; let i = 1;
var a = ++i; // (*) let a = ++i; // (*)
alert(a); // *!*2*/!* alert(a); // *!*2*/!*
``` ```
@ -273,8 +273,8 @@ Now let's use the postfix form:
```js ```js
//+ run //+ run
var i = 1; let i = 1;
var a = i++; // (*) let a = i++; // (*)
alert(a); // *!*1*/!* alert(a); // *!*1*/!*
``` ```
@ -286,7 +286,7 @@ In the line `(*)` the *postfix* form `i++` also increments `i`, but returns the
```js ```js
//+ run //+ run
var i = 0; let i = 0;
i++; i++;
++i; ++i;
alert( i ); // 2, the lines above did the same alert( i ); // 2, the lines above did the same
@ -297,7 +297,7 @@ alert( i ); // 2, the lines above did the same
```js ```js
//+ run //+ run
var i = 0; let i = 0;
alert( ++i ); // 1 alert( ++i ); // 1
``` ```
@ -306,7 +306,7 @@ alert( ++i ); // 1
```js ```js
//+ run //+ run
var i = 0; let i = 0;
alert( i++ ); // 0 alert( i++ ); // 0
``` ```
@ -318,7 +318,7 @@ An attentive reader could note that `++` (as well as `--`) can use as a part of
```js ```js
//+ run //+ run
var i = 1; let i = 1;
alert( 2 * ++i ); // 4 alert( 2 * ++i ); // 4
``` ```
@ -326,7 +326,7 @@ Compare with:
```js ```js
//+ run //+ run
var i = 1; let i = 1;
alert( 2 * i++ ); // 2, because i++ returns the pre-increment value alert( 2 * i++ ); // 2, because i++ returns the pre-increment value
``` ```
@ -337,7 +337,7 @@ Three lines, one line -- one action is much better:
```js ```js
//+ run //+ run
var i = 1; let i = 1;
alert( 2 * i ); alert( 2 * i );
i++; i++;
``` ```
@ -374,7 +374,7 @@ We often need to apply an operator to a variable and keep the result in it.
For example: For example:
```js ```js
var n = 2; let n = 2;
n = n + 5; n = n + 5;
n = n * 2; n = n * 2;
``` ```
@ -383,7 +383,7 @@ This notation can be shortened using operators `+=` and *=`:
```js ```js
//+ run //+ run
var n = 2; let n = 2;
n += 5; // now n=7 (same as n = n + 5) n += 5; // now n=7 (same as n = n + 5)
n *= 2; // now n=14 (same as n = n * 2) n *= 2; // now n=14 (same as n = n * 2)
@ -396,7 +396,7 @@ The call has the same precedence as a normal assignment, so it executes after mo
```js ```js
//+ run //+ run
var n = 2; let n = 2;
n *= 3 + 5; n *= 3 + 5;
alert( n ); // 16 (n = 2 * 8) alert( n ); // 16 (n = 2 * 8)

View file

@ -39,9 +39,9 @@ Boolean values can be assigned directly, just like any other values:
```js ```js
//+ run //+ run
var a = true; // assign directly let a = true; // assign directly
var b = 3 > 4; // assign the result of the comparison let b = 3 > 4; // assign the result of the comparison
alert( b ); // false alert( b ); // false
alert( a == b ); // false (cause a=true, b=false) alert( a == b ); // false (cause a=true, b=false)
@ -118,10 +118,10 @@ For example:
```js ```js
//+ run //+ run
var a = 0; let a = 0;
alert( Boolean(a) ); // false alert( Boolean(a) ); // false
var b = "0"; let b = "0";
alert( Boolean(b) ); // true alert( Boolean(b) ); // true
alert(a == b); // true! alert(a == b); // true!