|
| 1 | +# Տիպերի վերափոխումը JS-ում։ Ի՞նչ հնարավորություններ և ծուղակներ ունի իր մեջ ԹՈՒՅԼ տիպաբանությունը։ Ուղղակի և անուղղակի վերափոխումներ: |
| 2 | + |
| 3 | +**JavaScript**-ը չափազանց հանդուրժողական վերաբերմունք ունի տարբեր տիպերին պատկանող արժեքներով թվաբանական կամ այլ տիպի օպերացիաների կատարման հարցում։ Այն դեպքում, երբ օպերատորը կամ ֆունկցիան սպասում են որ օպերանդի կամ արգումենտի արժեքը պետք է լինի ասենք թե թվային, սակայն նա ստանում է տողային արժեք, ապա սխալ վերադարձնելու փոխարեն լեզվի ինտերպրետատորը հիմնվելով **ECMAScript** ստանդարտով սահմանված կանոնների վրա, փորձում է այն վերափոխել թվային արժեքի և շարունակել ծրագրի անխափան աշխատանքը: |
| 4 | + |
| 5 | +Դա բխում է լեզվի որդեգրած թույլ տիպաբանության փիլիսոփայությունից, երբ կատարվում է տիպերի անուղղակի վերափոխումներ, որպեսզի ծրագիրը շարունակի աշխատել։ Այն հանդիսանում է **JavaScript**-ի ամենակարևոր առանձնահատկություններից մեկը, որը թեև թույլ է տալիս գրել կարճ, բայց ընթեռնելի կոդ, սակայն լի է նաև վտանգներով, քանի-որ անուղղակի փոխակերպումների արդյունքում մենք կարող ենք ստանալ ոչ այն, ինչ ցանկանում էինք։ Սա նաև **JavaScript**-ի ամենաքննադատվող առանձնահատկությունն է, քանի-որ շատերը չհասկանալով թե ինչ սկզբունքով են կատարվում այդ փոխակերպումները, **JavaScript**-ը համարում են տարօրինակ լեզու, որտեղ ինչ գրում ես, աշխատում է, բայց ոչ այնպես, ինչպես նախատեսել ես: |
| 6 | + |
| 7 | +Որոշակի օբյեկտիվություն այդ քննադատությունների մեջ այնուամենայնիվ կա։ Քանի-որ թույլ տիպաբանությունը ստիպում է կոդում մեծացնել տարբեր լրացուցիչ ստուգումների քանակությունը, նաև համեմատած ուժեղ տիպաբանությամբ լեզուների՝ ահագին բարդացնում է ծրագրի թեսթավորումը։ |
| 8 | + |
| 9 | +Լավ բան է թույլ տիպաբանությունը թե ոչ՝ տեսակետները կարող են սկզբունքորեն տարբերվել, այն մի շարք առավելություններ ունի, սակայն ունի նաև ահռելի քանակությամբ թաքնված վտանգներ։ Ուղղակի պետք է ընդունել այն որպես փաստ, և փորձել օգտվել նրա ընձեռած հնարավորություններից և խուսափել ստեղծած «ստորջրյա խութերից»։ |
| 10 | + |
| 11 | +Գոյություն ունեն 3 առավել տարածված փոխակերպումներ՝ _տեքստային (տողային), թվային և տրամաբանական_: |
| 12 | + |
| 13 | +- **`Տողային փոխակերպումները`** կարելի է անել ուղղակիորեն՝ `String(value)` ֆունկցիայի միջոցով։ Օրինակ՝ |
| 14 | + |
| 15 | +```js |
| 16 | +String(12); // թվային արժեք 12-ը կվերափոխվի տողային արժեք "12"-ի։ |
| 17 | +String(true); // Բուլյան արժեք true-ն կվերափոխվի տողային արժեք "true"-ի |
| 18 | +``` |
| 19 | + |
| 20 | +Տողային փոխակերպումները լինում են նաև անուղղակի կերպով, երբ ֆունկցիան կամ օպերատորը սպասում են տողային արժեք, սակայն մենք տալիս ենք ուրիշ տիպի արժեք։ Օրինակ `alert(value)` ֆունկցիային եթե որպես արժեք տանք թիվ, այն կվերափոխվի տողի։ Կամ եթե տողային արժեքին գումարենք թվային արժեք՝ _"2" + 5 == "25":_ Տեսնելով, որ ձախ կողմի օպերանդը տող է, ինտերպրետատորը ենթադրում է, որ + օպերատորը մենք օգտագործում ենք ոչ թե որպես թվաբանական գումարման օպերատոր, այլ որպես տողերի համակցման (concatenation) օպերատոր, և 5 թվային արժեքը նույնպես վերածում է տողային արժեքի և կատարում տողերի համակցում: Պետք է նշել, որ այդ փոխակերպումը կատարելուց, ինտերպրետատորը խստորեն հետևում է ստանդարտով սահմանված տիպերի փոխակերպումների կանոններին։ |
| 21 | + |
| 22 | +- **`Թվային փոխակերպումները`** լինում են մաթեմատիկական ֆունկցիաների և արտահայտությունների մեջ։ |
| 23 | + |
| 24 | +Օրինակ եթե փորձենք տողերը բաժանել իրար վրա՝ _"8" / "2"_, ապա կստանանք 4, որովհետև հասկանալով որ մենք կատարում ենք թվաբանական գործողություն, ինտերպրետատորը, կրկին հենվելով լեզվական ստանդարտով խստորեն սահմանված կանոններին, փորձում է տողային արժեքը վերածել թվայինի: Մենք կարող ենք այլ տիպի արժեքներից ստանալ թվային արժեք ուղղակիորեն՝ `Number(value)` ֆունկցիայի միջոցով։ |
| 25 | + |
| 26 | +Կարևոր է հիշել, որ թվային վերափոխման ժամանակ դատարկ տողը վերածվում է 0-ի, եթե տողը դատարկ չէ, սկզբի և վերջի բացատները անտեսվում են, և մնացած մասից փորձ է կատարվում թիվը «կարդալ»։ Եթե հաջողությամբ չի պսակվում, արդյունքը լինում է _NaN_: |
| 27 | + |
| 28 | +Բուլյան _true_ արժեքը վերածվում է 1-ի, _false_-ը՝ 0-ի։ |
| 29 | +_Null_-ը վերափոխվում է 0-ի, իսկ _undefined_-ը՝ _NaN_-ի։ |
| 30 | + |
| 31 | +Վերջին վերափոխումը շատ կարևոր է հիշել, որովհետև ամենահաճախն է դառնում սխալների պատճառ։ |
| 32 | + |
| 33 | +Բոլոր մաթեմատիկական օպերատորները (միակ բացառությունը + օպերատորն է) տարբեր տիպերի պատկանող արժեքները փորձում են անուղղակիորեն վերածել թվի։ |
| 34 | +Օրինակ հետևյալ արտահայտության արժեքը կլինի՝ |
| 35 | + |
| 36 | +```js |
| 37 | +"8" * 3 - null - true; // 23 |
| 38 | +``` |
| 39 | + |
| 40 | +Կատարվել են անուղղակի փոխակերպումներ,"8"-ը վերածվել է 8-ի, null-ը 0-ի և true-ն 1-ի։ |
| 41 | + |
| 42 | +- **Ամենահասարակը `տրամաբանական փոխակերպումներն են`**։ Դրանք կատարվում են ուղղակիորեն `Boolean(value)` ֆունկցիայի օգնությամբ, ինչպես նաև անուղղակիորեն՝ օրինակ _if else, switch_ ու մի շարք այլ կոնստրուկցիաների և ցիկլերի պայմանի ստուգման բլոկում։ Փոխակերպման օրինաչափությունը հետևյալն է՝ այն արժեքները, որոնք ինտուիտիվ կերպով «դատարկ» են, վերածվում են _false_-ի, մնացած բոլորը՝ _true_ են։ |
| 43 | + |
| 44 | +**falsy** արժեքները հետևյալն են՝ |
| 45 | + |
| 46 | +- 0 |
| 47 | +- -0 |
| 48 | +- 0n (BigInt) |
| 49 | +- null |
| 50 | +- undefined |
| 51 | +- false |
| 52 | +- NaN |
| 53 | +- "" (դատարկ տող) |
| 54 | + |
| 55 | +Եթե որոշ աղբյուրներում հանդիպեք որ _falsy_ արժեքները 6-ն են, այլ ոչ թե 8-ը, պետք չի զարմանալ, քանի-որ երբեմն -0-ն առանձին չեն նշում, համարելով որ այն նույն 0-ն է և ուղղակի **JavaScript**-ում թվի ներկայացման այսպես կոչված **double-precision** 64 բիթային համակարգի օգտագործման տարօրինակ հետևանքը, և որ գործնականում դրա գոյությունը մեծ խնդիրներ չի առաջացնում, թեև մաթեմատիկոսների տեսանկյունից դրա գոյությունն իսկ արդեն տարօրինակություն է: Իսկ **BigInt** տվյալների տիպը համեմատաբար վերջերս է ավելացել, և առօրյա գործնական խնդիրների մեջ քիչ է օգտագործվում և շատերը միտումնավոր անտեսում կամ մոռանում են, որ լեզվի մեջ այդպիսի նոր տիպ կա: |
| 56 | + |
| 57 | +Բացի այս 8 արժեքից, մնացած բոլոր գոյություն ունեցող արժեքները տիպերի տրամաբանական վերափոխման ժամանակ վերածվում են _true_-ի, ի դեպ այդ թվում նաև դատարկ զանգվածները կամ օբյեկտները, ինչպես նաև տողը, որն իր մեջ պարունակում է 0 կամ բացատ ("0", " "): |
| 58 | + |
| 59 | +Որպես տիպերի վերափոխման օրինակ, [այս հղումով](https://dorey.github.io/JavaScript-Equality-Table/) ծանոթացեք մի շատ պատկերավոր աղյուսակի հետ, որտեղ ցուցադրվում է, թե ինչպես է իրեն դրսևորում ոչ խիստ հավասարության օպերատորը **==** _a և b_ տարբեր տիպերի համար։ |
0 commit comments