Skip to content

Commit d416310

Browse files
committed
final polish
1 parent e3e32d6 commit d416310

File tree

1 file changed

+49
-46
lines changed
  • 1-js/04-object-basics/09-object-toprimitive

1 file changed

+49
-46
lines changed

Diff for: 1-js/04-object-basics/09-object-toprimitive/article.md

+49-46
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
Ce se întâmplă atunci când obiectele sunt adunate `obj1 + obj2`, scăzute `obj1 - obj2` sau tipărite folosind `alert(obj)`?
55

6-
JavaScript nu prea permite să personalizeze cum operatorii lucrează pe obiecte. Spre deosebire de alte limbaje de programare, cum ar fi Ruby sau C++, nu putem implementa o metodă specială de obiect pentru a gestiona o adunare (sau alți operatori).
6+
JavaScript nu permite să personalizați modul în care operatorii lucrează pe obiecte. Spre deosebire de alte limbaje de programare, cum ar fi Ruby sau C++, nu putem implementa o metodă specială de obiect pentru a gestiona o adunare (sau alți operatori).
77

88
În cazul unor astfel de operații, obiectele sunt convertite automat în primitive, iar apoi operația este efectuată asupra acestor primitive și are ca rezultat o valoare primitivă.
99

10-
Aceasta este o limitare importantă, deoarece rezultatul a `obj1 + obj2` nu poate fi un alt obiect!
10+
Aceasta este o limitare importantă: rezultatul lui `obj1 + obj2` (sau altă operație matematică) nu poate fi un alt obiect!
1111

1212
E.g. nu putem crea obiecte reprezentând vectori sau matrici (sau realizări sau orice altceva), să le adunăm și să ne așteptăm ca rezultat un obiect "însumat". Astfel de realizări arhitecturale sunt automat "în afara discuției".
1313

@@ -26,13 +26,17 @@ Avem două scopuri:
2626

2727
1. Într-un context boolean toate obiectele sunt `true` (adevărate). Există doar conversii numerice și conversii de șiruri.
2828
2. Conversia numerică are loc atunci când scădem obiecte sau aplicăm funcții matematice. De exemplu, obiectele de tip `Date` (ce vor fi studiate în capitolul <info:date>) pot fi scăzute, iar rezultatul `date1 - date2` este diferența de timp dintre cele două date.
29-
3. În ceea ce privește conversia șirului - se întâmplă de obicei atunci când afișăm un obiect precum `alert(obj)` și în contexte similare.
29+
3. În ceea ce privește conversia șirului -- se întâmplă de obicei atunci când afișăm un obiect precum `alert(obj)` și în contexte similare.
3030

31-
Putem regla fin șirurile și conversia numerică, folosind metode speciale de obiecte.
31+
Putem implementa singuri conversia șirurilor de caractere și a numerelor, folosind metode de obiect speciale.
3232

33-
Există trei variante de conversie de tip, care se întâmplă în diferite situații.
33+
Acum să intrăm în detalii tehnice, pentru că este singura modalitate de a acoperi subiectul în profunzime.
3434

35-
Se numesc "indicii", așa cum sunt descrise în [specificația](https://tc39.github.io/ecma262/#sec-toprimitive):
35+
## Hints
36+
37+
Cum decide JavaScript ce conversie să aplice?
38+
39+
Există trei variante de conversie de tip, care se întâmplă în diverse situații. Acestea se numesc "indicii", așa cum sunt descrise în [specificație](https://tc39.github.io/ecma262/#sec-toprimitive):
3640

3741
`"string"`
3842
: Pentru o conversie obiect-la-șir, atunci când efectuăm o operație asupra unui obiect care se așteaptă la un șir, cum ar fi `alert`:
@@ -60,52 +64,52 @@ Se numesc "indicii", așa cum sunt descrise în [specificația](https://tc39.git
6064
let greater = user1 > user2;
6165
```
6266

67+
Majoritatea funcțiilor matematice încorporate includ, de asemenea, o astfel de conversie.
68+
6369
`"default"`
6470
: Se întâmplă în cazuri rare când operatorul nu este „sigur” la ce tip să se aștepte.
6571

6672
De exemplu, operatorul binar plus `+` poate funcționa atât cu șiruri (le concatenează) cât și cu numere (le adună), deci atât șirurile cât și numerele se acceptă. Așadar dacă un plus binar obține un obiect ca argument, acesta folosește indiciul `"default"` pentru a-l converti.
6773

68-
De asemenea dacă un obiect este comparat folosind `==` cu un șir, un număr sau un simbol, nu este clar ce conversie ar trebui efectuată, deci se utilizează indiciul `"default"`.
74+
De asemenea, dacă un obiect este comparat folosind `==` cu un șir, un număr sau un simbol, nu este clar ce conversie ar trebui efectuată, deci se utilizează indiciul `"default"`.
6975

7076
```js
71-
// binary plus uses the "default" hint
77+
// binary plus utilizează indiciul "default".
7278
let total = obj1 + obj2;
7379

74-
// obj == number uses the "default" hint
80+
// obj == number utilizează indiciul "default"
7581
if (user == 1) { ... };
7682
```
7783

7884
Operatorii de comparație mai mare și mai mic, cum ar fi `<` `>`, pot funcționa atât cu șiruri cât și cu numere. Totuși, ei folosesc indiciul `"number"`, nu `"default"`. Asta din motive istorice.
7985

80-
În practică însă, nu trebuie să ne amintim aceste detalii particulare, deoarece toate obiectele built-in cu excepția unui singur caz (obiectul `Date`, îl vom învăța mai târziu) implementează conversia `"default"` în același mod ca și `"number"`. Și noi putem face la fel.
86+
În practică însă, lucrurile sunt puțin mai simple.
8187

82-
```smart header="No `\"boolean\"` hint"
83-
Please note -- there are only three hints. It's that simple.
88+
Toate obiectele încorporate cu excepția unui singur caz (obiectul `Date`, îl vom învăța mai târziu), implementează conversia `"default"` în același mod ca și `"number"`. Și probabil că ar trebui să facem la fel.
8489

85-
There is no "boolean" hint (all objects are `true` in boolean context) or anything else. And if we treat `"default"` and `"number"` the same, like most built-ins do, then there are only two conversions.
86-
```
90+
Totuși, este important să cunoaștem toate cele 3 indicații, în curând vom vedea de ce.
8791

8892
**Pentru a face conversia, JavaScript încearcă să găsească și să apeleze trei metode obiect:**
8993

9094
1. Apelează `obj[Symbol.toPrimitive](indiciu)` - metoda cu cheia simbolică `Symbol.toPrimitive` (simbol de sistem), dacă o astfel de metodă există,
9195
2. În caz contrar, dacă indiciul este `"string"`
92-
- încearcă `obj.toString()` și `obj.valueOf()`, oricare dintre ele există.
93-
3. Altfel, dacă indiciul este `"number"` sau `"default"`
94-
- încearcă `obj.valueOf()` și `obj.toString()`, oricare dintre ele există.
96+
- încearcă să apeleze `obj.toString()` sau `obj.valueOf()`, oricare dintre ele există.
97+
3. Altfel dacă indiciul este `"number"` sau `"default"`
98+
- încearcă să apeleze `obj.valueOf()` sau `obj.toString()`, oricare dintre ele există.
9599

96100
## Symbol.toPrimitive
97101

98-
Să începem de la prima metodă. Există un simbol încorporat numit `Symbol.toPrimitive` care ar trebui utilizat pentru a denumi metoda de conversie, astfel:
102+
Să începem de la prima metodă. Există un simbol încorporat numit `Symbol.toPrimitive` care ar trebui utilizat pentru a denumi metoda de conversie, astfel:
99103

100104
```js
101105
obj[Symbol.toPrimitive] = function(hint) {
102106
// iată codul pentru a converti acest obiect într-o primitivă
103107
// trebuie să returneze o valoare primitivă
104-
// hint = unul dintre "string", "number", "default"
108+
// indiciu = unul dintre "string", "number", "default"
105109
};
106110
```
107111

108-
Dacă există metoda `Symbol.toPrimitive`, aceasta este utilizată pentru toate indiciile și nu mai sunt necesare alte metode.
112+
Dacă există metoda `Symbol.toPrimitive`, aceasta este utilizată pentru toate indiciile, și nu mai sunt necesare alte metode.
109113

110114
De exemplu, aici obiectul `user` o implementează:
111115

@@ -114,35 +118,34 @@ let user = {
114118
name: "John",
115119
money: 1000,
116120

117-
[Symbol.toPrimitive](indiciu) {
118-
alert(`indiciu: ${indiciu}`);
119-
return indiciu == "string" ? `{name: "${this.name}"}` : this.money;
121+
[Symbol.toPrimitive](hint) {
122+
alert(`indiciu: ${hint}`);
123+
return hint == "string" ? `{name: "${this.name}"}` : this.money;
120124
}
121125
};
122126

123-
// conversie demo:
127+
// conversii demo:
124128
alert(user); // indiciu: string -> {name: "John"}
125129
alert(+user); // indiciu: number -> 1000
126130
alert(user + 500); // indiciu: default -> 1500
127131
```
128132

129133
După cum putem vedea din cod, obiectul `user` devine un șir autodescriptiv sau o sumă de bani în funcție de conversie. Metoda unică `user[Symbol.toPrimitive]` gestionează toate cazurile de conversie.
130134

131-
132135
## toString/valueOf
133136

134137
Dacă nu există `Symbol.toPrimitive`, atunci JavaScript încearcă să găsească metodele `toString` și `valueOf`:
135138

136-
- Pentru indiciul "string": `toString`, iar dacă nu există, atunci `valueOf` (deci `toString` are prioritate pentru conversiile de stringuri).
137-
- Pentru alte indicii: `valueOf`, iar dacă nu există, atunci `toString` (astfel încât `valueOf` are prioritate pentru conversii matematice).
139+
- Pentru indiciul "string": apelează metoda `toString`, și dacă nu există sau dacă returnează un obiect în loc de o valoare primitivă, atunci apelează `valueOf` (deci `toString` are prioritate pentru conversiile de șiruri).
140+
- Pentru alte indicii: apelează `valueOf`, iar dacă acesta nu există sau dacă returnează un obiect în loc de o valoare primitivă, atunci apelează `toString` (deci `valueOf` are prioritate pentru matematică).
138141

139-
Metodele `toString` și `valueOf` provin din timpuri străvechi. Ele nu sunt simboluri (simbolurile nu existau cu mult timp în urmă), ci mai degrabă metode "obișnuite" cu nume de șir de caractere. Ele oferă o modalitate alternativă "în stil vechi" de a implementa conversia.
142+
Metodele `toString` și `valueOf` provin din timpuri străvechi. Ele nu sunt simboluri (simbolurile nu existau cu mult timp în urmă), ci mai degrabă metode "obișnuite" cu nume de șiruri. Ele oferă o modalitate alternativă "în stil vechi" de a implementa conversia.
140143

141144
Aceste metode trebuie să returneze o valoare primitivă. Dacă `toString` sau `valueOf` returnează un obiect, atunci este ignorată (la fel ca în cazul în care nu ar exista nicio metodă).
142145

143146
În mod implicit, un obiect simplu are următoarele metode `toString` și `valueOf`:
144147

145-
- Metoda `toString` returnează un șir de caractere `"[object Object Object]"`.
148+
- Metoda `toString` returnează un șir `"[object Object]"`.
146149
- Metoda `valueOf` returnează obiectul în sine.
147150

148151
Iată demonstrația:
@@ -154,7 +157,7 @@ alert(user); // [object Object]
154157
alert(user.valueOf() === user); // true
155158
```
156159

157-
Așadar, dacă încercăm să folosim un obiect ca șir de caractere, cum ar fi într-un `alert` sau așa ceva, atunci, în mod implicit, vom vedea `[object Object]`.
160+
Așadar, dacă încercăm să folosim un obiect ca șir de caractere, cum ar fi într-un `alert` sau așa ceva, atunci vom vedea în mod implicit `[object Object]`.
158161

159162
Valoarea implicită `valueOf` este menționată aici doar de dragul completării, pentru a evita orice confuzie. După cum puteți vedea, acesta returnează obiectul în sine, deci este ignorat. Nu mă întrebați de ce, aceea este din motive istorice. Deci putem presupune că nu există.
160163

@@ -203,7 +206,7 @@ alert(user + 500); // toString -> John500
203206

204207
În absența metodelor `Symbol.toPrimitive` și `valueOf`, `toString` va gestiona toate conversiile primitive.
205208

206-
### A conversion can return any primitive type
209+
### O conversie poate returna orice tip primitiv
207210

208211
Lucrul important de știut despre toate metodele de conversie primitivă este că nu returnează neapărat primitiva "indicată".
209212

@@ -212,7 +215,7 @@ Nu se poate controla dacă `toString` returnează exact un șir, sau dacă metod
212215
Singurul lucru obligatoriu: aceste metode trebuie să returneze o primitivă, nu un obiect.
213216

214217
```smart header="Note istorice"
215-
Din motive istorice, dacă `toString` sau `valueOf` returnează un obiect, nu este o eroare, dar o astfel de valoare este ignorată (ca și cum metoda nu ar exista). Asta deoarece mai demult, în JavaScript nu exista un concept de "eroare" sănătos.
218+
Din motive istorice, dacă `toString` sau `valueOf` returnează un obiect, nu este o eroare, dar o astfel de valoare este ignorată (ca și cum metoda nu ar exista). Asta deoarece în vremuri străvechi nu exista un concept de "eroare" bun în JavaScript.
216219
217220
În contrast, `Symbol.toPrimitive` *trebuie* să returneze o primitivă, altfel va exista o eroare.
218221
```
@@ -221,15 +224,15 @@ Din motive istorice, dacă `toString` sau `valueOf` returnează un obiect, nu es
221224

222225
După cum știm deja, mulți operatori și funcții efectuează conversii de tip, e.g. înmulțirea `*` convertește operanzii în numere.
223226

224-
Dacă trecem un obiect ca argument, atunci există două etape:
227+
Dacă transmitem un obiect ca argument, atunci există două etape de calcul:
225228
1. Obiectul este convertit într-o primitivă (folosind regulile descrise mai sus).
226-
2. Dacă primitiva rezultată nu este de tipul corect, aceasta este convertită.
229+
2. Dacă este necesar pentru calcule ulterioare, primitivul rezultat este de asemenea convertit.
227230

228231
De exemplu:
229232

230233
```js run
231234
let obj = {
232-
// toString se ocupă de toate conversiile în absența altor metode
235+
// toString gestionează toate conversiile în absența altor metode
233236
toString() {
234237
return "2";
235238
}
@@ -253,25 +256,25 @@ let obj = {
253256
alert(obj + 2); // 22 ("2" + 2), conversia în primitivă a returnat un șir => concatenare
254257
```
255258

256-
## Rezumat
259+
## Sumar
257260

258261
Conversia obiect-la-primitivă este apelată automat de multe funcții și operatori încorporați care așteaptă ca valoare o primitivă.
259262

260263
Există trei tipuri (indicii) ale acesteia:
261-
- `"string (șir)"` (pentru `alert` sau altă instrucțiune care are nevoie de un șir)
262-
- `"number (număr)"` (pentru matematică)
263-
- `"default (implicit)"` (câțiva operatori)
264+
- `"string"` (pentru `alert` sau altă instrucțiune care are nevoie de un șir)
265+
- `"number"` (pentru matematică)
266+
- `"default"` (câțiva operatori, de obicei obiectele îl implementează în același mod ca și `"number"`.)
264267

265-
Specificația descrie explicit ce operator folosește ce indiciu. Există foarte puțini operatori care "nu știu la ce să se aștepte" și folosesc indiciuul `"default"`. De obicei, pentru obiectele încorporate, indiciuul `"default"` în același mod ca `"number"`, astfel încât, în practică, ultimele două sunt adesea îmbinate între ele.
268+
Specificația descrie explicit ce operator folosește ce indiciu.
266269

267270
Algoritmul de conversie este:
268271

269-
1. Apelează `obj[Symbol.toPrimitive](hint)` dacă metoda există,
272+
1. Apelează `obj[Symbol.toPrimitive](indiciu)` dacă metoda există,
270273
2. În caz contrar, dacă indiciul este `"string"`
271-
- încearcă `obj.toString()` și `obj.valueOf()`, oricare dintre ele există.
272-
3. Altfel, dacă indiciul este `"number"` sau `"default"`
273-
- încearcă `obj.valueOf()` și `obj.toString()`, oricare dintre ele există.
274+
- încearcă să apeleze `obj.toString()` sau `obj.valueOf()`, oricare dintre ele există.
275+
3. Altfel dacă indiciul este `"number"` sau `"default"`
276+
- încearcă să apeleze `obj.valueOf()` sau `obj.toString()`, oricare dintre ele există.
274277

275-
În practică, este adesea suficient implementăm doar `obj.toString()` ca metodă "catch-all" pentru conversiile de șiruri care ar trebui să returneze o reprezentare "lizibilă pentru oameni" a unui obiect, în scopuri de logare sau de depanare.
278+
Toate aceste metode trebuie să returneze o primitivă pentru a funcționa (dacă sunt definite).
276279

277-
În ceea ce privește operațiile matematice, JavaScript nu oferă o modalitate de a le "suprascrie" cu ajutorul metodelor, deci proiectele din viața reală le folosesc rareori pe obiecte.
280+
În practică, este adesea suficient să implementăm doar `obj.toString()` ca metodă "catch-all" pentru conversiile de șiruri care ar trebui să returneze o reprezentare "lizibilă pentru oameni" a unui obiect, în scopuri de logare sau de depanare.

0 commit comments

Comments
 (0)