Skip to content

Commit 4f6356b

Browse files
authored
Merge pull request #5 from javascript-tutorial/master
Updated Repo
2 parents 5a71d10 + 3e93486 commit 4f6356b

File tree

44 files changed

+178
-188
lines changed

Some content is hidden

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

44 files changed

+178
-188
lines changed

1-js/01-getting-started/1-intro/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ JavaScript's abilities in the browser are limited for the sake of the user's saf
6363

6464
Examples of such restrictions include:
6565

66-
- JavaScript on a webpage may not read/write arbitrary files on the hard disk, copy them or execute programs. It has no direct access to OS system functions.
66+
- JavaScript on a webpage may not read/write arbitrary files on the hard disk, copy them or execute programs. It has no direct access to OS functions.
6767

6868
Modern browsers allow it to work with files, but the access is limited and only provided if the user does certain actions, like "dropping" a file into a browser window or selecting it via an `<input>` tag.
6969

1-js/02-first-steps/02-structure/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ But it should be two separate statements, not one. Such a merging in this case i
9494

9595
We recommend putting semicolons between statements even if they are separated by newlines. This rule is widely adopted by the community. Let's note once again -- *it is possible* to leave out semicolons most of the time. But it's safer -- especially for a beginner -- to use them.
9696

97-
## Comments
97+
## Comments [#code-comments]
9898

9999
As time goes on, programs become more and more complex. It becomes necessary to add *comments* which describe what the code does and why.
100100

@@ -136,7 +136,7 @@ alert('World');
136136
```
137137

138138
```smart header="Use hotkeys!"
139-
In most editors, a line of code can be commented out by pressing the `key:Ctrl+/` hotkey for a single-line comment and something like `key:Ctrl+Shift+/` -- for multiline comments (select a piece of code and press the hotkey). For Mac, try `key:Cmd` instead of `key:Ctrl`.
139+
In most editors, a line of code can be commented out by pressing the `key:Ctrl+/` hotkey for a single-line comment and something like `key:Ctrl+Shift+/` -- for multiline comments (select a piece of code and press the hotkey). For Mac, try `key:Cmd` instead of `key:Ctrl` and `key:Option` instead of `key:Shift`.
140140
```
141141

142142
````warn header="Nested comments are not supported!"

1-js/02-first-steps/07-operators/article.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ Here's an extract from the [precedence table](https://developer.mozilla.org/en/J
138138
| Precedence | Name | Sign |
139139
|------------|------|------|
140140
| ... | ... | ... |
141-
| 16 | unary plus | `+` |
142-
| 16 | unary negation | `-` |
143-
| 14 | multiplication | `*` |
144-
| 14 | division | `/` |
141+
| 17 | unary plus | `+` |
142+
| 17 | unary negation | `-` |
143+
| 15 | multiplication | `*` |
144+
| 15 | division | `/` |
145145
| 13 | addition | `+` |
146146
| 13 | subtraction | `-` |
147147
| ... | ... | ... |

1-js/02-first-steps/12-while-for/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ For even values of `i`, the `continue` directive stops executing the body and pa
256256
````smart header="The `continue` directive helps decrease nesting"
257257
A loop that shows odd values could look like this:
258258

259-
```js
259+
```js run
260260
for (let i = 0; i < 10; i++) {
261261

262262
if (i % 2) {
@@ -268,7 +268,7 @@ for (let i = 0; i < 10; i++) {
268268

269269
From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`.
270270

271-
But as a side-effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of`if` is longer than a few lines, that may decrease the overall readability.
271+
But as a side-effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability.
272272
````
273273
274274
````warn header="No `break/continue` to the right side of '?'"

1-js/03-code-quality/02-coding-style/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ For example:
8686
```js
8787
// backtick quotes ` allow to split the string into multiple lines
8888
let str = `
89-
Ecma International's TC39 is a group of JavaScript developers,
89+
ECMA International's TC39 is a group of JavaScript developers,
9090
implementers, academics, and more, collaborating with the community
9191
to maintain and evolve the definition of JavaScript.
9292
`;

1-js/04-object-basics/01-object/article.md

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ For multiword properties, the dot access doesn't work:
101101
user.likes birds = true
102102
```
103103

104-
That's because the dot requires the key to be a valid variable identifier. That is: no spaces and other limitations.
104+
JavaScript doesn't understand that. It thinks that we address `user.likes`, and then gives a syntax error when comes across unexpected `birds`.
105+
106+
The dot requires the key to be a valid variable identifier. That implies: contains no spaces, doesn't start with a digit and doesn't include special characters (`$` и `_` are allowed).
105107

106108
There's an alternative "square bracket notation" that works with any string:
107109

@@ -203,43 +205,6 @@ Square brackets are much more powerful than the dot notation. They allow any pro
203205

204206
So most of the time, when property names are known and simple, the dot is used. And if we need something more complex, then we switch to square brackets.
205207

206-
207-
208-
````smart header="Reserved words are allowed as property names"
209-
A variable cannot have a name equal to one of language-reserved words like "for", "let", "return" etc.
210-
211-
But for an object property, there's no such restriction. Any name is fine:
212-
213-
```js run
214-
let obj = {
215-
for: 1,
216-
let: 2,
217-
return: 3
218-
};
219-
220-
alert( obj.for + obj.let + obj.return ); // 6
221-
```
222-
223-
Basically, any name is allowed, but there's a special one: `"__proto__"` that gets special treatment for historical reasons. For instance, we can't set it to a non-object value:
224-
225-
```js run
226-
let obj = {};
227-
obj.__proto__ = 5;
228-
alert(obj.__proto__); // [object Object], didn't work as intended
229-
```
230-
231-
As we see from the code, the assignment to a primitive `5` is ignored.
232-
233-
That can become a source of bugs and even vulnerabilities if we intend to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys.
234-
235-
In that case the visitor may choose `__proto__` as the key, and the assignment logic will be ruined (as shown above).
236-
237-
There is a way to make objects treat `__proto__` as a regular property, which we'll cover later, but first we need to know more about objects.
238-
239-
There's also another data structure [Map](info:map-set), that we'll learn in the chapter <info:map-set>, which supports arbitrary keys.
240-
````
241-
242-
243208
## Property value shorthand
244209

245210
In real code we often use existing variables as values for property names.
@@ -284,7 +249,63 @@ let user = {
284249
};
285250
```
286251

287-
## Existence check
252+
## Property names limitations
253+
254+
Property names (keys) must be either strings or symbols (a special type for identifiers, to be covered later).
255+
256+
Other types are automatically converted to strings.
257+
258+
For instance, a number `0` becomes a string `"0"` when used as a property key:
259+
260+
```js run
261+
let obj = {
262+
0: "test" // same as "0": "test"
263+
};
264+
265+
// both alerts access the same property (the number 0 is converted to string "0")
266+
alert( obj["0"] ); // test
267+
alert( obj[0] ); // test (same property)
268+
```
269+
270+
**Reserved words are allowed as property names.**
271+
272+
As we already know, a variable cannot have a name equal to one of language-reserved words like "for", "let", "return" etc.
273+
274+
But for an object property, there's no such restriction. Any name is fine:
275+
276+
```js run
277+
let obj = {
278+
for: 1,
279+
let: 2,
280+
return: 3
281+
};
282+
283+
alert( obj.for + obj.let + obj.return ); // 6
284+
```
285+
286+
We can use any string as a key, but there's a special property named `__proto__` that gets special treatment for historical reasons.
287+
288+
For instance, we can't set it to a non-object value:
289+
290+
```js run
291+
let obj = {};
292+
obj.__proto__ = 5; // assign a number
293+
alert(obj.__proto__); // [object Object] - the value is an object, didn't work as intended
294+
```
295+
296+
As we see from the code, the assignment to a primitive `5` is ignored.
297+
298+
The nature of `__proto__` will be revealed in detail later in the chapter [](info:prototype-inheritance).
299+
300+
As for now, it's important to know that such behavior of `__proto__` can become a source of bugs and even vulnerabilities if we intend to store user-provided keys in an object.
301+
302+
The problem is that a visitor may choose `__proto__` as the key, and the assignment logic will be ruined (as shown above).
303+
304+
There are two workarounds for the problem:
305+
1. Modify the object's behavior to treat `__proto__` as a regular property. We'll learn how to do it in the chapter [](info:prototype-methods).
306+
2. Using [Map](info:map-set) data structure which supports arbitrary keys. We'll learn it in the chapter <info:map-set>.
307+
308+
## Property existence test, "in" operator
288309

289310
A notable objects feature is that it's possible to access any property. There will be no error if the property doesn't exist! Accessing a non-existing property just returns `undefined`. It provides a very common way to test whether the property exists -- to get it and compare vs undefined:
290311

1-js/04-object-basics/03-symbol/article.md

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ let id = Symbol();
1818

1919
Upon creation, we can give symbol a description (also called a symbol name), mostly useful for debugging purposes:
2020

21-
```js run
21+
```js
2222
// id is a symbol with the description "id"
2323
let id = Symbol("id");
2424
```
@@ -178,22 +178,6 @@ alert( clone[id] ); // 123
178178

179179
There's no paradox here. That's by design. The idea is that when we clone an object or merge objects, we usually want *all* properties to be copied (including symbols like `id`).
180180

181-
````smart header="Property keys of other types are coerced to strings"
182-
We can only use strings or symbols as keys in objects. Other types are converted to strings.
183-
184-
For instance, a number `0` becomes a string `"0"` when used as a property key:
185-
186-
```js run
187-
let obj = {
188-
0: "test" // same as "0": "test"
189-
};
190-
191-
// both alerts access the same property (the number 0 is converted to string "0")
192-
alert( obj["0"] ); // test
193-
alert( obj[0] ); // test (same property)
194-
```
195-
````
196-
197181
## Global symbols
198182

199183
As we've seen, usually all symbols are different, even if they have the same name. But sometimes we want same-named symbols to be same entities. For instance, different parts of our application want to access symbol `"id"` meaning exactly the same property.
@@ -241,7 +225,7 @@ alert( Symbol.keyFor(sym) ); // name
241225
alert( Symbol.keyFor(sym2) ); // id
242226
```
243227

244-
The `Symbol.keyFor` internally uses the global symbol registry to look up the key for the symbol. So it doesn't work for non-global symbols. If the symbol is not global, it won't be able to find it and return `undefined`.
228+
The `Symbol.keyFor` internally uses the global symbol registry to look up the key for the symbol. So it doesn't work for non-global symbols. If the symbol is not global, it won't be able to find it and returns `undefined`.
245229

246230
That said, any symbols have `description` property.
247231

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ The "right" algorithm to do string comparisons is more complex than it may seem,
534534

535535
So, the browser needs to know the language to compare.
536536

537-
Luckily, all modern browsers (IE10- requires the additional library [Intl.JS](https://github.com/andyearnshaw/Intl.js/)) support the internationalization standard [ECMA 402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf).
537+
Luckily, all modern browsers (IE10- requires the additional library [Intl.js](https://github.com/andyearnshaw/Intl.js/)) support the internationalization standard [ECMA-402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf).
538538

539539
It provides a special method to compare strings in different languages, following their rules.
540540

1-js/05-data-types/04-array/10-maximal-subarray/task.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ The task is: find the contiguous subarray of `arr` with the maximal sum of items
1010

1111
Write the function `getMaxSubSum(arr)` that will return that sum.
1212

13-
For instance:
13+
For instance:
1414

1515
```js
16-
getMaxSubSum([-1, *!*2, 3*/!*, -9]) = 5 (the sum of highlighted items)
17-
getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) = 6
18-
getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) = 11
19-
getMaxSubSum([-2, -1, *!*1, 2*/!*]) = 3
20-
getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) = 100
21-
getMaxSubSum([*!*1, 2, 3*/!*]) = 6 (take all)
16+
getMaxSubSum([-1, *!*2, 3*/!*, -9]) == 5 (the sum of highlighted items)
17+
getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) == 6
18+
getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) == 11
19+
getMaxSubSum([-2, -1, *!*1, 2*/!*]) == 3
20+
getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) == 100
21+
getMaxSubSum([*!*1, 2, 3*/!*]) == 6 (take all)
2222
```
2323

2424
If all items are negative, it means that we take none (the subarray is empty), so the sum is zero:

1-js/05-data-types/05-array-methods/12-reduce-object/task.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ let users = [
2020
let usersById = groupById(users);
2121

2222
/*
23-
// after the call we have:
23+
// after the call we should have:
2424
2525
usersById = {
2626
john: {id: 'john', name: "John Smith", age: 20}

0 commit comments

Comments
 (0)