Skip to content

Commit f6118dd

Browse files
committed
Merge branch 'master' of github.com:javascript-tutorial/en.javascript.info into sync-b300836f
2 parents 775eb3d + b300836 commit f6118dd

128 files changed

Lines changed: 2022 additions & 421 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1-js/02-first-steps/15-function-expressions-arrows/article.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -196,19 +196,20 @@ First, the syntax: how to differentiate between them in the code.
196196

197197
The more subtle difference is *when* a function is created by the JavaScript engine.
198198

199-
**A Function Expression is created when the execution reaches it and is usable from then on.**
199+
**A Function Expression is created when the execution reaches it and is usable only from that moment.**
200200

201201
Once the execution flow passes to the right side of the assignment `let sum = function…` -- here we go, the function is created and can be used (assigned, called, etc. ) from now on.
202202

203203
Function Declarations are different.
204204

205-
**A Function Declaration is usable in the whole script (or a code block, if it's inside a block).**
205+
**A Function Declaration can be called earlier than it is defined.**
206206

207-
In other words, when JavaScript *prepares* to run the script or a code block, it first looks for Function Declarations in it and creates the functions. We can think of it as an "initialization stage".
207+
For example, a global Function Declaration is visible in the whole script, no matter where it is.
208208

209-
And after all of the Function Declarations are processed, the execution goes on.
209+
That's due to internal algorithms. When JavaScript prepares to run the script, it first looks for global Function Declarations in it and creates the functions. We can think of it as an "initialization stage".
210+
211+
And after all Function Declarations are processed, the code is executed. So it has access to these functions.
210212

211-
As a result, a function declared as a Function Declaration can be called earlier than it is defined.
212213

213214
For example, this works:
214215

@@ -224,7 +225,7 @@ function sayHi(name) {
224225

225226
The Function Declaration `sayHi` is created when JavaScript is preparing to start the script and is visible everywhere in it.
226227

227-
...If it was a Function Expression, then it wouldn't work:
228+
...If it were a Function Expression, then it wouldn't work:
228229

229230
```js run refresh untrusted
230231
*!*
@@ -238,13 +239,11 @@ let sayHi = function(name) { // (*) no magic any more
238239

239240
Function Expressions are created when the execution reaches them. That would happen only in the line `(*)`. Too late.
240241

241-
**When a Function Declaration is made within a code block, it is visible everywhere inside that block. But not outside of it.**
242-
243-
Sometimes that's handy to declare a local function only needed in that block alone. But that feature may also cause problems.
242+
**In strict mode, when a Function Declaration is within a code block, it's visible everywhere inside that block. But not outside of it.**
244243

245244
For instance, let's imagine that we need to declare a function `welcome()` depending on the `age` variable that we get during runtime. And then we plan to use it some time later.
246245

247-
The code below doesn't work:
246+
If we use Function Declaration, it won't work as intended:
248247

249248
```js run
250249
let age = prompt("What is your age?", 18);
@@ -350,12 +349,12 @@ welcome(); // ok now
350349
```
351350

352351

353-
```smart header="When should you choose Function Declaration versus Function Expression?"
354-
As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax, the one we used before. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
352+
```smart header="When to choose Function Declaration versus Function Expression?"
353+
As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
355354
356-
It's also a little bit easier to look up `function f(…) {…}` in the code than `let f = function(…) {…}`. Function Declarations are more "eye-catching".
355+
That's also better for readability, as it's easier to look up `function f(…) {…}` in the code than `let f = function(…) {…}`. Function Declarations are more "eye-catching".
357356
358-
...But if a Function Declaration does not suit us for some reason (we've seen an example above), then Function Expression should be used.
357+
...But if a Function Declaration does not suit us for some reason, or we need a conditional declaration (we've just seen an example), then Function Expression should be used.
359358
```
360359

361360

1-js/05-data-types/03-string/1-ucfirst/solution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ But we can make a new string based on the existing one, with the uppercased firs
66
let newStr = str[0].toUpperCase() + str.slice(1);
77
```
88

9-
There's a small problem though. If `str` is empty, then `str[0]` is undefined, so we'll get an error.
9+
There's a small problem though. If `str` is empty, then `str[0]` is `undefined`, and as `undefined` doesn't have the `toUpperCase()` method, we'll get an error.
1010

1111
There are two variants here:
1212

1-js/05-data-types/03-string/1-ucfirst/task.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ importance: 5
22

33
---
44

5-
# Uppercast the first character
5+
# Uppercase the first character
66

77
Write a function `ucFirst(str)` that returns the string `str` with the uppercased first character, for instance:
88

1-js/05-data-types/03-string/article.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ Examples with unicode:
8686

8787
```js run
8888
alert( "\u00A9" ); // ©
89-
alert( "\u{20331}" ); // 佫, a rare chinese hieroglyph (long unicode)
89+
alert( "\u{20331}" ); // 佫, a rare Chinese hieroglyph (long unicode)
9090
alert( "\u{1F60D}" ); // 😍, a smiling face symbol (another long unicode)
9191
```
9292

9393
All special characters start with a backslash character `\`. It is also called an "escape character".
9494

95-
We would also use it if we want to insert a quote into the string.
95+
We might also use it if we wanted to insert a quote into the string.
9696

9797
For instance:
9898

@@ -305,7 +305,8 @@ if (str.indexOf("Widget") != -1) {
305305
}
306306
```
307307

308-
````smart header="The bitwise NOT trick"
308+
#### The bitwise NOT trick
309+
309310
One of the old tricks used here is the [bitwise NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) `~` operator. It converts the number to a 32-bit integer (removes the decimal part if exists) and then reverses all bits in its binary representation.
310311

311312
For 32-bit integers the call `~n` means exactly the same as `-(n+1)` (due to IEEE-754 format).
@@ -321,9 +322,9 @@ alert( ~-1 ); // 0, the same as -(-1+1)
321322
*/!*
322323
```
323324

324-
As we can see, `~n` is zero only if `n == -1`.
325+
As we can see, `~n` is zero only if `n == -1` (that's for any 32-bit signed integer `n`).
325326

326-
So, the test `if ( ~str.indexOf("...") )` is truthy that the result of `indexOf` is not `-1`. In other words, when there is a match.
327+
So, the test `if ( ~str.indexOf("...") )` is truthy only if the result of `indexOf` is not `-1`. In other words, when there is a match.
327328

328329
People use it to shorten `indexOf` checks:
329330

@@ -338,7 +339,10 @@ if (~str.indexOf("Widget")) {
338339
It is usually not recommended to use language features in a non-obvious way, but this particular trick is widely used in old code, so we should understand it.
339340

340341
Just remember: `if (~str.indexOf(...))` reads as "if found".
341-
````
342+
343+
Technically speaking, numbers are truncated to 32 bits by `~` operator, so there exist other big numbers that give `0`, the smallest is `~4294967295=0`. That makes such check is correct only if a string is not that long.
344+
345+
Right now we can see this trick only in the old code, as modern JavaScript provides `.includes` method (see below).
342346

343347
### includes, startsWith, endsWith
344348

@@ -558,7 +562,7 @@ You can skip the section if you don't plan to support them.
558562

559563
### Surrogate pairs
560564

561-
Most symbols have a 2-byte code. Letters in most european languages, numbers, and even most hieroglyphs, have a 2-byte representation.
565+
All frequently used characters have 2-byte codes. Letters in most european languages, numbers, and even most hieroglyphs, have a 2-byte representation.
562566

563567
But 2 bytes only allow 65536 combinations and that's not enough for every possible symbol. So rare symbols are encoded with a pair of 2-byte characters called "a surrogate pair".
564568

@@ -567,7 +571,7 @@ The length of such symbols is `2`:
567571
```js run
568572
alert( '𝒳'.length ); // 2, MATHEMATICAL SCRIPT CAPITAL X
569573
alert( '😂'.length ); // 2, FACE WITH TEARS OF JOY
570-
alert( '𩷶'.length ); // 2, a rare chinese hieroglyph
574+
alert( '𩷶'.length ); // 2, a rare Chinese hieroglyph
571575
```
572576

573577
Note that surrogate pairs did not exist at the time when JavaScript was created, and thus are not correctly processed by the language!
@@ -628,7 +632,7 @@ For instance:
628632

629633
```js run
630634
alert( 'S\u0307\u0323' ); // Ṩ, S + dot above + dot below
631-
alert( 'S\u0323\u0307' ); // Ṩ, S + dot below + dot above
635+
alert( 'S\u0323\u0307' ); // Ṩ, S + dot below + dot above
632636

633637
alert( 'S\u0307\u0323' == 'S\u0323\u0307' ); // false
634638
```
@@ -649,7 +653,7 @@ alert( "S\u0307\u0323".normalize().length ); // 1
649653
alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
650654
```
651655

652-
In reality, this is not always the case. The reason being that the symbol `Ṩ` is "common enough", so UTF-16 creators included it in the main table and gave it the code.
656+
In reality, this is not always the case. The reason being that the symbol `` is "common enough", so UTF-16 creators included it in the main table and gave it the code.
653657

654658
If you want to learn more about normalization rules and variants -- they are described in the appendix of the Unicode standard: [Unicode Normalization Forms](http://www.unicode.org/reports/tr15/), but for most practical purposes the information from this section is enough.
655659

1-js/05-data-types/10-date/1-new-date/solution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
The `new Date` constructor uses the local time zone by default. So the only important thing to remember is that months start from zero.
1+
The `new Date` constructor uses the local time zone. So the only important thing to remember is that months start from zero.
22

33
So February has number 1.
44

1-js/05-data-types/10-date/4-get-date-ago/task.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Create a function `getDateAgo(date, days)` to return the day of month `days` ago
88

99
For instance, if today is 20th, then `getDateAgo(new Date(), 1)` should be 19th and `getDateAgo(new Date(), 2)` should be 18th.
1010

11-
Should also work over months/years reliably:
11+
Should work reliably for `days=365` or more:
1212

1313
```js
1414
let date = new Date(2015, 0, 2);

1-js/05-data-types/10-date/article.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ To create a new `Date` object call `new Date()` with one of the following argume
4040
```js run
4141
let date = new Date("2017-01-26");
4242
alert(date);
43-
// The time portion of the date is assumed to be midnight GMT and
43+
// The time is not set, so it's assumed to be midnight GMT and
4444
// is adjusted according to the timezone the code is run in
4545
// So the result could be
4646
// Thu Jan 26 2017 11:00:00 GMT+1100 (Australian Eastern Daylight Time)
@@ -51,8 +51,6 @@ To create a new `Date` object call `new Date()` with one of the following argume
5151
`new Date(year, month, date, hours, minutes, seconds, ms)`
5252
: Create the date with the given components in the local time zone. Only the first two arguments are obligatory.
5353

54-
Note:
55-
5654
- The `year` must have 4 digits: `2013` is okay, `98` is not.
5755
- The `month` count starts with `0` (Jan), up to `11` (Dec).
5856
- The `date` parameter is actually the day of month, if absent then `1` is assumed.
@@ -74,7 +72,7 @@ To create a new `Date` object call `new Date()` with one of the following argume
7472

7573
## Access date components
7674

77-
There are many methods to access the year, month and so on from the `Date` object. But they can be easily remembered when categorized.
75+
There are methods to access the year, month and so on from the `Date` object:
7876

7977
[getFullYear()](mdn:js/Date/getFullYear)
8078
: Get the year (4 digits)
@@ -217,21 +215,21 @@ The important side effect: dates can be subtracted, the result is their differen
217215
That can be used for time measurements:
218216
219217
```js run
220-
let start = new Date(); // start counting
218+
let start = new Date(); // start measuring time
221219

222220
// do the job
223221
for (let i = 0; i < 100000; i++) {
224222
let doSomething = i * i * i;
225223
}
226224

227-
let end = new Date(); // done
225+
let end = new Date(); // end measuring time
228226

229227
alert( `The loop took ${end - start} ms` );
230228
```
231229
232230
## Date.now()
233231
234-
If we only want to measure the difference, we don't need the `Date` object.
232+
If we only want to measure time, we don't need the `Date` object.
235233
236234
There's a special method `Date.now()` that returns the current timestamp.
237235
@@ -264,6 +262,8 @@ If we want a reliable benchmark of CPU-hungry function, we should be careful.
264262
265263
For instance, let's measure two functions that calculate the difference between two dates: which one is faster?
266264
265+
Such performance measurements are often called "benchmarks".
266+
267267
```js
268268
// we have date1 and date2, which function faster returns their difference in ms?
269269
function diffSubtract(date1, date2) {
@@ -280,7 +280,7 @@ These two do exactly the same thing, but one of them uses an explicit `date.getT
280280
281281
So, which one is faster?
282282
283-
The first idea may be to run them many times in a row and measure the time difference. For our case, functions are very simple, so we have to do it around 100000 times.
283+
The first idea may be to run them many times in a row and measure the time difference. For our case, functions are very simple, so we have to do it at least 100000 times.
284284
285285
Let's measure:
286286
@@ -310,7 +310,7 @@ Wow! Using `getTime()` is so much faster! That's because there's no type convers
310310
311311
Okay, we have something. But that's not a good benchmark yet.
312312
313-
Imagine that at the time of running `bench(diffSubtract)` CPU was doing something in parallel, and it was taking resources. And by the time of running `bench(diffGetTime)` the work has finished.
313+
Imagine that at the time of running `bench(diffSubtract)` CPU was doing something in parallel, and it was taking resources. And by the time of running `bench(diffGetTime)` that work has finished.
314314
315315
A pretty real scenario for a modern multi-process OS.
316316
@@ -368,7 +368,7 @@ for (let i = 0; i < 10; i++) {
368368
```
369369
370370
```warn header="Be careful doing microbenchmarking"
371-
Modern JavaScript engines perform many optimizations. They may tweak results of "artificial tests" compared to "normal usage", especially when we benchmark something very small. So if you seriously want to understand performance, then please study how the JavaScript engine works. And then you probably won't need microbenchmarks at all.
371+
Modern JavaScript engines perform many optimizations. They may tweak results of "artificial tests" compared to "normal usage", especially when we benchmark something very small, such as how an operator works, or a built-in function. So if you seriously want to understand performance, then please study how the JavaScript engine works. And then you probably won't need microbenchmarks at all.
372372

373373
The great pack of articles about V8 can be found at <http://mrale.ph>.
374374
```
@@ -415,7 +415,7 @@ alert(date);
415415

416416
Note that unlike many other systems, timestamps in JavaScript are in milliseconds, not in seconds.
417417

418-
Also, sometimes we need more precise time measurements. JavaScript itself does not have a way to measure time in microseconds (1 millionth of a second), but most environments provide it. For instance, browser has [performance.now()](mdn:api/Performance/now) that gives the number of milliseconds from the start of page loading with microsecond precision (3 digits after the point):
418+
Sometimes we need more precise time measurements. JavaScript itself does not have a way to measure time in microseconds (1 millionth of a second), but most environments provide it. For instance, browser has [performance.now()](mdn:api/Performance/now) that gives the number of milliseconds from the start of page loading with microsecond precision (3 digits after the point):
419419

420420
```js run
421421
alert(`Loading started ${performance.now()}ms ago`);

1-js/09-classes/01-class/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
119119

120120
## Not just a syntax sugar
121121

122-
Sometimes people say that `class` is a "syntax sugar" in JavaScript, because we could actually declare the same without `class` keyword at all:
122+
Sometimes people say that `class` is a "syntax sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new) in JavaScript, because we could actually declare the same without `class` keyword at all:
123123

124124
```js run
125125
// rewriting class User in pure functions

1-js/09-classes/03-static-properties-methods/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ class User {
1717
User.staticMethod(); // true
1818
```
1919

20-
That actually does the same as assigning it as a function property:
20+
That actually does the same as assigning it as a property:
2121

2222
```js
23-
function User() { }
23+
class User() { }
2424

2525
User.staticMethod = function() {
2626
alert(this === User);
5 Bytes
Loading

0 commit comments

Comments
 (0)