Skip to content

Commit 96342b3

Browse files
authored
Merge pull request #205 from javascript-tutorial/sync-3a0b3f4e
Sync with upstream @ 3a0b3f4
2 parents 7d1dc8a + 82a94da commit 96342b3

File tree

12 files changed

+117
-124
lines changed

12 files changed

+117
-124
lines changed

1-js/01-getting-started/2-manuals-specifications/article.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,12 @@ E mais, se você está desenvolvendo para browsers, há outras especificações
1717

1818
## Manuais
1919

20-
- **MDN (Mozilla) JavaScript Reference** é um manual com exemplos e outras informações. É ótimo para um entendimento sobre funções, métodos da linguagem, etc.
20+
- **MDN (Mozilla) JavaScript Reference** é um manual com exemplos e outras informações. É ótimo para um entendimento sobre funções da linguagem, métodos , etc.
2121

2222
Pode ser encontrado em <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference>.
2323

2424
Porém, às vezes é melhor fazer uma busca na internet. Apenas use "MDN [termo]" na busca, por exemplo: <https://google.com/search?q=MDN+parseInt> para procurar pela função `parseInt`.
2525

26-
- **MSDN** - Manual da Microsoft com muitas informações, incluindo JavaScript (frequentemente referido como JScript). Se precisar de algo específico para o Internet Explorer, é melhor ir por aqui: <http://msdn.microsoft.com/>.
27-
28-
Assim como para o manual da Mozilla, também podemos fazer uma busca na internet com frases do tipo "RegExp MSDN" ou "RegExp MSDN jscript".
29-
3026
## Tabelas de compatibilidade
3127

3228
JavaScript é uma linguagem em desenvolvimento, novas funcionalidades são adicionadas regularmente.

1-js/03-code-quality/02-coding-style/code-style.svg

Lines changed: 1 addition & 1 deletion
Loading

1-js/04-object-basics/03-garbage-collection/article.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ Simply put, "reachable" values are those that are accessible or usable somehow.
1414

1515
For instance:
1616

17-
- Local variables and parameters of the current function.
18-
- Variables and parameters for other functions on the current chain of nested calls.
17+
- The currently executing function, its local variables and parameters.
18+
- Other functions on the current chain of nested calls, their local variables and parameters.
1919
- Global variables.
2020
- (there are some other, internal ones as well)
2121

@@ -207,6 +207,6 @@ A general book "The Garbage Collection Handbook: The Art of Automatic Memory Man
207207

208208
If you are familiar with low-level programming, the more detailed information about V8 garbage collector is in the article [A tour of V8: Garbage Collection](http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection).
209209

210-
[V8 blog](http://v8project.blogspot.com/) also publishes articles about changes in memory management from time to time. Naturally, to learn the garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](http://mrale.ph) who worked as one of V8 engineers. I'm saying: "V8", because it is best covered with articles in the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
210+
[V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn the garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](http://mrale.ph) who worked as one of V8 engineers. I'm saying: "V8", because it is best covered with articles in the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
211211

212212
In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language.

1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ describe("calculator", function() {
1515
afterEach(function() {
1616
prompt.restore();
1717
});
18+
19+
it('the read get two values and saves them as object properties', function () {
20+
assert.equal(calculator.a, 2);
21+
assert.equal(calculator.b, 3);
22+
});
1823

1924
it("the sum is 5", function() {
2025
assert.equal(calculator.sum(), 5);
Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11

22
describe("calculator", function() {
3-
let calculator;
4-
before(function() {
5-
sinon.stub(window, "prompt")
6-
7-
prompt.onCall(0).returns("2");
8-
prompt.onCall(1).returns("3");
9-
10-
calculator = new Calculator();
11-
calculator.read();
12-
});
13-
14-
it("when 2 and 3 are entered, the sum is 5", function() {
15-
assert.equal(calculator.sum(), 5);
16-
});
17-
18-
it("when 2 and 3 are entered, the product is 6", function() {
19-
assert.equal(calculator.mul(), 6);
20-
});
21-
22-
after(function() {
23-
prompt.restore();
3+
let calculator;
4+
before(function() {
5+
sinon.stub(window, "prompt")
6+
7+
prompt.onCall(0).returns("2");
8+
prompt.onCall(1).returns("3");
9+
10+
calculator = new Calculator();
11+
calculator.read();
12+
});
13+
14+
it("the read method asks for two values using prompt and remembers them in object properties", function() {
15+
assert.equal(calculator.a, 2);
16+
assert.equal(calculator.b, 3);
17+
});
18+
19+
it("when 2 and 3 are entered, the sum is 5", function() {
20+
assert.equal(calculator.sum(), 5);
21+
});
22+
23+
it("when 2 and 3 are entered, the product is 6", function() {
24+
assert.equal(calculator.mul(), 6);
25+
});
26+
27+
after(function() {
28+
prompt.restore();
29+
});
2430
});
25-
});
31+

1-js/04-object-basics/06-constructor-new/article.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ let user = new function() {
8383
The constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse.
8484
````
8585

86-
## Dual-syntax constructors: new.target
86+
## Constructor mode test: new.target
8787

8888
```smart header="Advanced stuff"
8989
The syntax from this section is rarely used, skip it unless you want to know everything.
9090
```
9191

9292
Inside a function, we can check whether it was called with `new` or without it, using a special `new.target` property.
9393

94-
It is empty for regular calls and equals the function if called with `new`:
94+
It is undefined for regular calls and equals the function if called with `new`:
9595

9696
```js run
9797
function User() {
@@ -109,7 +109,9 @@ new User(); // function User { ... }
109109
*/!*
110110
```
111111

112-
That can be used to allow both `new` and regular calls to work the same. That is, create the same object:
112+
That can be used inside the function to know whether it was called with `new`, "in constructor mode", or without it, "in regular mode".
113+
114+
We can also make both `new` and regular calls to do the same, like this:
113115

114116
```js run
115117
function User(name) {
@@ -210,6 +212,8 @@ john = {
210212
*/
211213
```
212214

215+
To create complex objects, there's a more advanced syntax, [classes](info:classes), that we'll cover later.
216+
213217
## Summary
214218

215219
- Constructor functions or, briefly, constructors, are regular functions, but there's a common agreement to name them with capital letter first.

1-js/04-object-basics/07-optional-chaining/article.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ That's why the optional chaining `?.` was added to the language. To solve this p
7474

7575
## Optional chaining
7676

77-
The optional chaining `?.` stops the evaluation if the part before `?.` is `undefined` or `null` and returns that part.
77+
The optional chaining `?.` stops the evaluation if the value before `?.` is `undefined` or `null` and returns `undefined`.
7878

7979
**Further in this article, for brevity, we'll be saying that something "exists" if it's not `null` and not `undefined`.**
8080

8181
In other words, `value?.prop`:
82-
- is the same as `value.prop` if `value` exists,
82+
- works as `value.prop`, if `value` exists,
8383
- otherwise (when `value` is `undefined/null`) it returns `undefined`.
8484

8585
Here's the safe way to access `user.address.street` using `?.`:
@@ -103,7 +103,7 @@ alert( user?.address.street ); // undefined
103103
104104
Please note: the `?.` syntax makes optional the value before it, but not any further.
105105
106-
E.g. in `user?.address.street.name` the `?.` allows `user` to be `null/undefined`, but it's all it does. Further properties are accessed in a regular way. If we want some of them to be optional, then we'll need to replace more `.` with `?.`.
106+
E.g. in `user?.address.street.name` the `?.` allows `user` to safely be `null/undefined` (and returns `undefined` in that case), but that's only for `user`. Further properties are accessed in a regular way. If we want some of them to be optional, then we'll need to replace more `.` with `?.`.
107107
108108
```warn header="Don't overuse the optional chaining"
109109
We should use `?.` only where it's ok that something doesn't exist.
@@ -173,18 +173,16 @@ Then `?.()` checks the left part: if the admin function exists, then it runs (th
173173
The `?.[]` syntax also works, if we'd like to use brackets `[]` to access properties instead of dot `.`. Similar to previous cases, it allows to safely read a property from an object that may not exist.
174174
175175
```js run
176+
let key = "firstName";
177+
176178
let user1 = {
177179
firstName: "John"
178180
};
179181

180-
let user2 = null; // Imagine, we couldn't authorize the user
181-
182-
let key = "firstName";
182+
let user2 = null;
183183

184184
alert( user1?.[key] ); // John
185185
alert( user2?.[key] ); // undefined
186-
187-
alert( user1?.[key]?.something?.not?.existing); // undefined
188186
```
189187
190188
Also we can use `?.` with `delete`:

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

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ A value of this type can be created using `Symbol()`:
1616
let id = Symbol();
1717
```
1818

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

2121
```js
2222
// id is a symbol with the description "id"
@@ -94,7 +94,7 @@ What's the benefit of using `Symbol("id")` over a string `"id"`?
9494

9595
As `user` objects belongs to another code, and that code also works with them, we shouldn't just add any fields to it. That's unsafe. But a symbol cannot be accessed accidentally, the third-party code probably won't even see it, so it's probably all right to do.
9696

97-
Imagine that another script wants to have its own "id" property inside `user`, for its own purposes. That may be another JavaScript library, so the scripts are completely unaware of each other.
97+
Also, imagine that another script wants to have its own identifier inside `user`, for its own purposes. That may be another JavaScript library, so that the scripts are completely unaware of each other.
9898

9999
Then that script can create its own `Symbol("id")`, like this:
100100

@@ -105,11 +105,11 @@ let id = Symbol("id");
105105
user[id] = "Their id value";
106106
```
107107

108-
There will be no conflict, because symbols are always different, even if they have the same name.
108+
There will be no conflict between our and their identifiers, because symbols are always different, even if they have the same name.
109109

110-
Now note that if we used a string `"id"` instead of a symbol for the same purpose, then there *would* be a conflict:
110+
...But if we used a string `"id"` instead of a symbol for the same purpose, then there *would* be a conflict:
111111

112-
```js run
112+
```js
113113
let user = { name: "John" };
114114

115115
// Our script uses "id" property
@@ -123,7 +123,7 @@ user.id = "Their id value"
123123

124124
### Symbols in an object literal
125125

126-
If we want to use a symbol in an object literal, we need square brackets.
126+
If we want to use a symbol in an object literal `{...}`, we need square brackets around it.
127127

128128
Like this:
129129

@@ -161,7 +161,7 @@ for (let key in user) alert(key); // name, age (no symbols)
161161
alert( "Direct: " + user[id] );
162162
```
163163

164-
That's a part of the general "hiding" concept. If another script or a library loops over our object, it won't unexpectedly access a symbolic property.
164+
`Object.keys(user)` also ignores them. That's a part of the general "hiding symbolic properties" principle. If another script or a library loops over our object, it won't unexpectedly access a symbolic property.
165165

166166
In contrast, [Object.assign](mdn:js/Object/assign) copies both string and symbol properties:
167167

@@ -180,13 +180,11 @@ There's no paradox here. That's by design. The idea is that when we clone an obj
180180

181181
## Global symbols
182182

183-
As we've seen, usually all symbols are different, even if they have the same names. But sometimes we want same-named symbols to be same entities.
184-
185-
For instance, different parts of our application want to access symbol `"id"` meaning exactly the same property.
183+
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.
186184

187185
To achieve that, there exists a *global symbol registry*. We can create symbols in it and access them later, and it guarantees that repeated accesses by the same name return exactly the same symbol.
188186

189-
In order to create or read a symbol in the registry, use `Symbol.for(key)`.
187+
In order to read (create if absent) a symbol from the registry, use `Symbol.for(key)`.
190188

191189
That call checks the global registry, and if there's a symbol described as `key`, then returns it, otherwise creates a new symbol `Symbol(key)` and stores it in the registry by the given `key`.
192190

@@ -196,7 +194,7 @@ For instance:
196194
// read from the global registry
197195
let id = Symbol.for("id"); // if the symbol did not exist, it is created
198196

199-
// read it again
197+
// read it again (maybe from another part of the code)
200198
let idAgain = Symbol.for("id");
201199

202200
// the same symbol
@@ -218,22 +216,29 @@ For global symbols, not only `Symbol.for(key)` returns a symbol by name, but the
218216
For instance:
219217

220218
```js run
219+
// get symbol by name
221220
let sym = Symbol.for("name");
222221
let sym2 = Symbol.for("id");
223222

224-
// get name from symbol
223+
// get name by symbol
225224
alert( Symbol.keyFor(sym) ); // name
226225
alert( Symbol.keyFor(sym2) ); // id
227226
```
228227

229228
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`.
230229

230+
That said, any symbols have `description` property.
231+
231232
For instance:
232233

233234
```js run
234-
alert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbol
235+
let globalSymbol = Symbol.for("name");
236+
let localSymbol = Symbol("name");
237+
238+
alert( Symbol.keyFor(globalSymbol) ); // name, global symbol
239+
alert( Symbol.keyFor(localSymbol) ); // undefined, not global
235240

236-
alert( Symbol.keyFor(Symbol("name2")) ); // undefined, the argument isn't a global symbol
241+
alert( localSymbol.description ); // name
237242
```
238243

239244
## System symbols
@@ -256,9 +261,9 @@ Other symbols will also become familiar when we study the corresponding language
256261

257262
`Symbol` is a primitive type for unique identifiers.
258263

259-
Symbols are created with `Symbol()` call with an optional description.
264+
Symbols are created with `Symbol()` call with an optional description (name).
260265

261-
Symbols are always different values, even if they have the same name. If we want same-named symbols to be equal, then we should use the global registry: `Symbol.for(key)` returns (creates if needed) a global symbol with `key` as the name. Multiple calls of `Symbol.for` return exactly the same symbol.
266+
Symbols are always different values, even if they have the same name. If we want same-named symbols to be equal, then we should use the global registry: `Symbol.for(key)` returns (creates if needed) a global symbol with `key` as the name. Multiple calls of `Symbol.for` with the same `key` return exactly the same symbol.
262267

263268
Symbols have two main use cases:
264269

@@ -269,4 +274,4 @@ Symbols have two main use cases:
269274

270275
2. There are many system symbols used by JavaScript which are accessible as `Symbol.*`. We can use them to alter some built-in behaviors. For instance, later in the tutorial we'll use `Symbol.iterator` for [iterables](info:iterable), `Symbol.toPrimitive` to setup [object-to-primitive conversion](info:object-toprimitive) and so on.
271276

272-
Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. So they are not really hidden. But most libraries, built-in methods and syntax constructs adhere to a common agreement that they are. And the one who explicitly calls the aforementioned methods probably understands well what he's doing.
277+
Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. So they are not really hidden. But most libraries, built-in functions and syntax constructs don't use these methods.

1-js/05-data-types/02-number/article.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,29 @@ Imagine we need to write 1 billion. The obvious way is:
1616
let billion = 1000000000;
1717
```
1818

19-
But in real life, we usually avoid writing a long string of zeroes as it's easy to mistype. Also, we are lazy. We will usually write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
19+
We also can use underscore `_` as the separator:
2020

21-
In JavaScript, we shorten a number by appending the letter `"e"` to the number and specifying the zeroes count:
21+
```js
22+
let billion = 1_000_000_000;
23+
```
24+
25+
Here the underscore `_` plays the role of the "syntactic sugar", it makes the number more readable. The JavaScript engine simply ignores `_` between digits, so it's exactly the same one billion as above.
26+
27+
In real life though, we try to avoid writing long sequences of zeroes. We're too lazy for that. We'll try to write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
28+
29+
In JavaScript, we can shorten a number by appending the letter `"e"` to it and specifying the zeroes count:
2230

2331
```js run
2432
let billion = 1e9; // 1 billion, literally: 1 and 9 zeroes
2533

26-
alert( 7.3e9 ); // 7.3 billions (7,300,000,000)
34+
alert( 7.3e9 ); // 7.3 billions (same as 7300000000 or 7_300_000_000)
2735
```
2836

29-
In other words, `"e"` multiplies the number by `1` with the given zeroes count.
37+
In other words, `e` multiplies the number by `1` with the given zeroes count.
3038

3139
```js
32-
1e3 = 1 * 1000
33-
1.23e6 = 1.23 * 1000000
40+
1e3 = 1 * 1000 // e3 means *1000
41+
1.23e6 = 1.23 * 1000000 // e6 means *1000000
3442
```
3543

3644
Now let's write something very small. Say, 1 microsecond (one millionth of a second):
@@ -125,7 +133,7 @@ There are several built-in functions for rounding:
125133
: Rounds up: `3.1` becomes `4`, and `-1.1` becomes `-1`.
126134

127135
`Math.round`
128-
: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4` and `-1.1` becomes `-1`.
136+
: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4`, the middle case: `3.5` rounds up to `4` too.
129137

130138
`Math.trunc` (not supported by Internet Explorer)
131139
: Removes anything after the decimal point without rounding: `3.1` becomes `3`, `-1.1` becomes `-1`.

1-js/05-data-types/10-destructuring-assignment/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ let [name1, name2] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
160160

161161
alert(name1); // Julius
162162
alert(name2); // Caesar
163-
// Furher items aren't assigned anywhere
163+
// Further items aren't assigned anywhere
164164
```
165165

166166
If we'd like also to gather all that follows -- we can add one more parameter that gets "the rest" using three dots `"..."`:

0 commit comments

Comments
 (0)