You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Made a few updates in 1-js/04-object-basics/ regarding grammar and translation, also added some missing pieces.
Fixed the conflicts for 1-js/06-advanced-functions/03-closure/article.md
Fixed conflicts from 11-async/02-promise-basics/article.md
Fixed conflicts for the main article and updated the tasks and solutions of 1-js/99-js-misc/01-proxy
Copy file name to clipboardExpand all lines: 1-js/04-object-basics/04-object-methods/article.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -70,7 +70,7 @@ OOP este un lucru mare, o știință interesantă în sine. Cum să alegi entit
70
70
Există o sintaxă mai scurtă pentru metode într-un obiect literal:
71
71
72
72
```js
73
-
// aceste obiecte realizează același lucru
73
+
// aceste obiecte fac același lucru
74
74
75
75
user = {
76
76
sayHi:function() {
@@ -90,7 +90,7 @@ user = {
90
90
91
91
După cum s-a demonstrat, putem omite `"function"` și scriem doar `sayHi()`.
92
92
93
-
În realitate, notațiile nu sunt complet identice. Există diferențe subtile legate de moștenirea obiectelor (care vor fi acoperite ulterior), dar deocamdată nu contează. În aproape toate cazurile, se preferă sintaxa mai scurtă.
93
+
Să spunem adevărul, notațiile nu sunt complet identice. Există diferențe subtile legate de moștenirea obiectelor (care vor fi acoperite ulterior), dar deocamdată nu contează. În aproape toate cazurile, se preferă sintaxa mai scurtă.
[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) le ignoră, de asemenea. Aceasta este o parte a principiului general "ascunderea proprietăților simbolice". Dacă un alt script sau librărie iterează asupra obiectului nostru, nu va accesa neașteptat o proprietate simbol.
174
175
175
-
În contrast, metoda [Object.assign](mdn:js/Object/assign) copiază proprietățile de ambele tipuri, șir și simbol:
176
+
În contrast, metoda [Object.assign](mdn:js/Object/assign) copiază atât proprietățile string cât și symbol:
176
177
177
178
```js run
178
179
let id =Symbol("id");
@@ -185,7 +186,7 @@ let clone = Object.assign({}, user);
185
186
alert( clone[id] ); // 123
186
187
```
187
188
188
-
Nu este niciun paradox aici. Așa este construit. Ideea este că, atunci când clonăm un obiect sau contopim obiecte, în mod normal vrem ca *toate* proprietățile să fie copiate (incluzând simboluri precum `id`).
189
+
Nu este niciun paradox aici. Așa este construit. Ideea este că, atunci când clonăm un obiect sau contopim obiecte, de obicei vrem ca *toate* proprietățile să fie copiate (incluzând simboluri precum `id`).
189
190
190
191
## Simboluri globale
191
192
@@ -284,4 +285,4 @@ Simbolurile au două cazuri principale de folosire:
284
285
285
286
2. Există multe simboluri sistem folosite de JavaScript care sunt accesibile prin `Symbol.*`. Le putem folosi pentru a altera câteva comportamente incluse în limbaj. De exemplu, mai târziu în tutorial vom folosi `Symbol.iterator` pentru [iterabile](info:iterable), `Symbol.toPrimitive` pentru a configura [conversia object-to-primitive](info:object-toprimitive) ș.a.m.d.
286
287
287
-
Tehnic, simbolurile nu sunt 100% ascunse. Există metode ale limbajului JavaScript[Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) care ne permit sa accesăm toate simbolurile. Mai există o metodă numită [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) care returnează *toate* cheile unui obiect incluzându-le și pe cele simbolice. Dar cele mai multe librării, funcții built-in și construcții de sintaxă nu folosesc aceste metode.
288
+
Tehnic, simbolurile nu sunt 100% ascunse. Există o metodă built-in[Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) care ne permit sa accesăm toate simbolurile. Mai există o metodă numită [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) care returnează *toate* cheile unui obiect incluzându-le și pe cele simbolice. Dar cele mai multe librării, funcții built-in și construcții de sintaxă nu folosesc aceste metode.
5. When the `counter()` is called, an "empty" Lexical Environment is created for it. It has no local variables by itself. But the `[[Environment]]` of `counter` is used as the outer reference for it, so it has access to the variables of the former `makeCounter()` call where it was created:
179
-
180
-

181
-
=======
182
-
5. When `counter()` is called, a new Lexical Environment is created for the call. It's empty, as `counter` has no local variables by itself. But the `[[Environment]]` of `counter` is used as the `outer` reference for it, that provides access to the variables of the former `makeCounter()` call where it was created:
183
-
>>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923
184
-
=======
185
176
This is the so-called *global* Lexical Environment, associated with the whole script.
186
-
>>>>>>> 29216730a877be28d0a75a459676db6e7f5c4834
187
177
188
178
On the picture above, the rectangle means Environment Record (variable store) and the arrow means the outer reference. The global Lexical Environment has no outer reference, that's why the arrow points to `null`.
189
179
@@ -195,20 +185,11 @@ Here's a little bit longer code:
195
185
196
186
Rectangles on the right-hand side demonstrate how the global Lexical Environment changes during the execution:
197
187
198
-
<<<<<<< HEAD
199
-

200
-
<<<<<<< HEAD
201
-
202
-
So we return to the previous step with the only change -- the new value of `count`. The following calls all do the same.
203
-
=======
204
-
>>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923
205
-
=======
206
188
1. When the script starts, the Lexical Environment is pre-populated with all declared variables.
207
189
- Initially, they are in the "Uninitialized" state. That's a special internal state, it means that the engine knows about the variable, but it cannot be referenced until it has been declared with `let`. It's almost the same as if the variable didn't exist.
208
190
2. Then `let phrase` definition appears. There's no assignment yet, so its value is `undefined`. We can use the variable from this point forward.
Copy file name to clipboardExpand all lines: 1-js/11-async/02-promise-basics/article.md
+49-33Lines changed: 49 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,18 +33,10 @@ When the executor obtains the result, be it soon or late, doesn't matter, it sho
33
33
34
34
So to summarize: the executor runs automatically and attempts to perform a job. When it is finished with the attempt, it calls `resolve` if it was successful or `reject` if there was an error.
35
35
36
-
<<<<<<< HEAD
37
-
<<<<<<< HEAD
38
-

39
-
=======
40
-
The `promise` object returned by `new Promise` constructor has internal properties:
41
-
>>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923
42
-
=======
43
36
The `promise` object returned by the `new Promise` constructor has these internal properties:
44
-
>>>>>>> 29216730a877be28d0a75a459676db6e7f5c4834
45
37
46
38
-`state` — initially `"pending"`, then changes to either `"fulfilled"` when `resolve` is called or `"rejected"` when `reject` is called.
47
-
-`result` — initially `undefined`, then changes to `value` when `resolve(value)` called or `error` when `reject(error)` is called.
39
+
-`result` — initially `undefined`, then changes to `value` when `resolve(value)`is called or `error` when `reject(error)` is called.
48
40
49
41
So the executor eventually moves `promise` to one of these states:
50
42
@@ -68,7 +60,7 @@ We can see two things by running the code above:
68
60
1. The executor is called automatically and immediately (by `new Promise`).
69
61
2. The executor receives two arguments: `resolve` and `reject`. These functions are pre-defined by the JavaScript engine, so we don't need to create them. We should only call one of them when ready.
70
62
71
-
After one second of "processing" the executor calls `resolve("done")` to produce the result. This changes the state of the `promise` object:
63
+
After one second of "processing", the executor calls `resolve("done")` to produce the result. This changes the state of the `promise` object:
72
64
73
65

74
66
@@ -135,9 +127,9 @@ That's fine. We immediately have a resolved promise.
135
127
The properties `state` and `result` of the Promise object are internal. We can't directly access them. We can use the methods `.then`/`.catch`/`.finally` for that. They are described below.
136
128
```
137
129
138
-
## Consumers: then, catch, finally
130
+
## Consumers: then, catch
139
131
140
-
A Promise object serves as a link between the executor (the "producing code" or "singer") and the consuming functions (the "fans"), which will receive the result or error. Consuming functions can be registered (subscribed) using methods `.then`, `.catch` and `.finally`.
132
+
A Promise object serves as a link between the executor (the "producing code" or "singer") and the consuming functions (the "fans"), which will receive the result or error. Consuming functions can be registered (subscribed) using the methods `.then`and `.catch`.
141
133
142
134
### then
143
135
@@ -152,9 +144,9 @@ promise.then(
152
144
);
153
145
```
154
146
155
-
The first argument of `.then` is a function that runs when the promise is resolved, and receives the result.
147
+
The first argument of `.then` is a function that runs when the promise is resolved and receives the result.
156
148
157
-
The second argument of `.then` is a function that runs when the promise is rejected, and receives the error.
149
+
The second argument of `.then` is a function that runs when the promise is rejected and receives the error.
158
150
159
151
For instance, here's a reaction to a successfully resolved promise:
160
152
@@ -220,59 +212,83 @@ promise.catch(alert); // shows "Error: Whoops!" after 1 second
220
212
221
213
The call `.catch(f)` is a complete analog of `.then(null, f)`, it's just a shorthand.
222
214
223
-
### finally
215
+
## Cleanup: finally
224
216
225
217
Just like there's a `finally` clause in a regular `try {...} catch {...}`, there's `finally` in promises.
226
218
227
-
The call `.finally(f)` is similar to `.then(f, f)` in the sense that `f` always runs when the promise is settled: be it resolve or reject.
219
+
The call `.finally(f)` is similar to `.then(f, f)` in the sense that `f` runs always, when the promise is settled: be it resolve or reject.
220
+
221
+
The idea of `finally` is to set up a handler for performing cleanup/finalizing after the previous operations are complete.
228
222
229
-
`finally` is a good handler for performing cleanup, e.g. stopping our loading indicators, as they are not needed anymore, no matter what the outcome is.
223
+
E.g. stopping loading indicators, closing no longer needed connections, etc.
230
224
231
-
Like this:
225
+
Think of it as a party finisher. No matter was a party good or bad, how many friends were in it, we still need (or at least should) do a cleanup after it.
226
+
227
+
The code may look like this:
232
228
233
229
```js
234
230
new Promise((resolve, reject) => {
235
-
/* do something that takes time, and then call resolve/reject */
231
+
/* do something that takes time, and then call resolve or maybe reject */
236
232
})
237
233
*!*
238
234
// runs when the promise is settled, doesn't matter successfully or not
239
235
.finally(() => stop loading indicator)
240
-
// so the loading indicator is always stopped before we process the result/error
236
+
// so the loading indicator is always stopped before we go on
241
237
*/!*
242
238
.then(result => show result, err => show error)
243
239
```
244
240
245
-
That said, `finally(f)` isn't exactly an alias of `then(f,f)` though. There are few subtle differences:
241
+
Please note that `finally(f)` isn't exactly an alias of `then(f,f)` though.
242
+
243
+
There are important differences:
246
244
247
245
1. A `finally` handler has no arguments. In `finally` we don't know whether the promise is successful or not. That's all right, as our task is usually to perform "general" finalizing procedures.
248
-
2. A `finally` handler passes through results and errors to the next handler.
246
+
247
+
Please take a look at the example above: as you can see, the `finally` handler has no arguments, and the promise outcome is handled by the next handler.
248
+
2. A `finally` handler "passes through" the result or error to the next suitable handler.
249
249
250
250
For instance, here the result is passed through `finally` to `then`:
251
+
251
252
```js run
252
253
new Promise((resolve, reject) => {
253
-
setTimeout(() => resolve("result"), 2000)
254
+
setTimeout(() => resolve("value"), 2000);
254
255
})
255
-
.finally(() => alert("Promise ready"))
256
-
.then(result => alert(result)); // <-- .then handles the result
256
+
.finally(() => alert("Promise ready")) // triggers first
And here there's an error in the promise, passed through `finally` to `catch`:
260
+
As you can see, the `value` returned by the first promise is passed through `finally` to the next `then`.
261
+
262
+
That's very convenient, because `finally` is not meant to process a promise result. As said, it's a place to do generic cleanup, no matter what the outcome was.
263
+
264
+
And here's an example of an error, for us to see how it's passed through `finally` to `catch`:
260
265
261
266
```js run
262
267
new Promise((resolve, reject) => {
263
268
throw new Error("error");
264
269
})
265
-
.finally(() => alert("Promise ready"))
266
-
.catch(err => alert(err)); // <-- .catch handles the error object
270
+
.finally(() => alert("Promise ready")) // triggers first
271
+
.catch(err => alert(err)); // <-- .catch shows the error
267
272
```
268
273
269
-
That's very convenient, because `finally` is not meant to process a promise result. So it passes it through.
274
+
3. A `finally` handler also shouldn't return anything. If it does, the returned value is silently ignored.
270
275
271
-
We'll talk more about promise chaining and result-passing between handlers in the next chapter.
276
+
The only exception to this rule is when a `finally` handler throws an error. Then this error goes to the next handler, instead of any previous outcome.
272
277
278
+
To summarize:
279
+
280
+
- A `finally` handler doesn't get the outcome of the previous handler (it has no arguments). This outcome is passed through instead, to the next suitable handler.
281
+
- If a `finally` handler returns something, it's ignored.
282
+
- When `finally` throws an error, then the execution goes to the nearest error handler.
283
+
284
+
These features are helpful and make things work just the right way if we use `finally` how it's supposed to be used: for generic cleanup procedures.
273
285
274
286
````smart header="We can attach handlers to settled promises"
275
-
If a promise is pending, `.then/catch/finally` handlers wait for it. Otherwise, if a promise has already settled, they just run:
287
+
If a promise is pending, `.then/catch/finally` handlers wait for its outcome.
288
+
289
+
Sometimes, it might be that a promise is already settled when we add a handler to it.
290
+
291
+
In such case, these handlers just run immediately:
276
292
277
293
```js run
278
294
// the promise becomes resolved immediately upon creation
@@ -286,10 +302,10 @@ Note that this makes promises more powerful than the real life "subscription lis
286
302
Promises are more flexible. We can add handlers any time: if the result is already there, they just execute.
287
303
````
288
304
289
-
Next, let's see more practical examples of how promises can help us write asynchronous code.
290
-
291
305
## Example: loadScript [#loadscript]
292
306
307
+
Next, let's see more practical examples of how promises can help us write asynchronous code.
308
+
293
309
We've got the `loadScript` function for loading a script from the previous chapter.
294
310
295
311
Here's the callback-based variant, just to remind us of it:
Copy file name to clipboardExpand all lines: 1-js/99-js-misc/01-proxy/article.md
-4Lines changed: 0 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -730,11 +730,7 @@ The problem is actually in the proxy, in the line `(*)`.
730
730
2. The prototype is `userProxy`.
731
731
3. When reading `name` property from the proxy, its `get` trap triggers and returns it from the original object as `target[prop]` in the line `(*)`.
732
732
733
-
<<<<<<< HEAD
734
-

735
-
=======
736
733
A call to `target[prop]`, when `prop` is a getter, runs its code in the context `this=target`. So the result is `this._name` from the original object `target`, that is: from `user`.
737
-
>>>>>>> 852ee189170d9022f67ab6d387aeae76810b5923
738
734
739
735
To fix such situations, we need `receiver`, the third argument of `get` trap. It keeps the correct `this` to be passed to a getter. In our case that's `admin`.
Rețineți că parantezele din jurul `(user.go)` nu fac nimic aici. De obicei setează ordinea operațiilor, dar aici punctul `.` are oricum precedență, deci nu are niciun efect. Singurul lucru care contează este simbolul ";".
43
-
=======
44
-
Please note that parentheses around `(user.go)` do nothing here. Usually they setup the order of operations, but here the dot `.` works first anyway, so there's no effect. Only the semicolon thing matters.
Vă rugăm să rețineți că parantezele din jurul `(user.go)` nu fac nimic aici. De obicei ele stabilesc ordinea operațiilor, dar aici punctul `.` funcționează primul oricum, deci nu au niciun efect. Doar chestia cu punctul și virgula contează.
0 commit comments