Տիպերի վերափոխումը JS-ում։ Ի՞նչ հնարավորություններ և ծուղակներ ունի իր մեջ ԹՈՒՅԼ տիպաբանությունը։ Ուղղակի և անուղղակի վերափոխումներ:
JavaScript-ը չափազանց հանդուրժողական վերաբերմունք ունի տարբեր տիպերին պատկանող արժեքներով թվաբանական կամ այլ տիպի օպերացիաների կատարման հարցում։ Այն դեպքում, երբ օպերատորը կամ ֆունկցիան սպասում են որ օպերանդի կամ արգումենտի արժեքը պետք է լինի ասենք թե թվային, սակայն նա ստանում է տողային արժեք, ապա սխալ վերադարձնելու փոխարեն լեզվի ինտերպրետատորը հիմնվելով ECMAScript ստանդարտով սահմանված կանոնների վրա, փորձում է այն վերափոխել թվային արժեքի և շարունակել ծրագրի անխափան աշխատանքը:
Դա բխում է լեզվի որդեգրած թույլ տիպաբանության փիլիսոփայությունից, երբ կատարվում է տիպերի անուղղակի վերափոխումներ, որպեսզի ծրագիրը շարունակի աշխատել։ Այն հանդիսանում է JavaScript-ի ամենակարևոր առանձնահատկություններից մեկը, որը թեև թույլ է տալիս գրել կարճ, բայց ընթեռնելի կոդ, սակայն լի է նաև վտանգներով, քանի-որ անուղղակի փոխակերպումների արդյունքում մենք կարող ենք ստանալ ոչ այն, ինչ ցանկանում էինք։ Սա նաև JavaScript-ի ամենաքննադատվող առանձնահատկությունն է, քանի-որ շատերը չհասկանալով թե ինչ սկզբունքով են կատարվում այդ փոխակերպումները, JavaScript-ը համարում են տարօրինակ լեզու, որտեղ ինչ գրում ես, աշխատում է, բայց ոչ այնպես, ինչպես նախատեսել ես:
Որոշակի օբյեկտիվություն այդ քննադատությունների մեջ այնուամենայնիվ կա։ Քանի-որ թույլ տիպաբանությունը ստիպում է կոդում մեծացնել տարբեր լրացուցիչ ստուգումների քանակությունը, նաև համեմատած ուժեղ տիպաբանությամբ լեզուների՝ ահագին բարդացնում է ծրագրի թեսթավորումը։
Լավ բան է թույլ տիպաբանությունը թե ոչ՝ տեսակետները կարող են սկզբունքորեն տարբերվել, այն մի շարք առավելություններ ունի, սակայն ունի նաև ահռելի քանակությամբ թաքնված վտանգներ։ Ուղղակի պետք է ընդունել այն որպես փաստ, և փորձել օգտվել նրա ընձեռած հնարավորություններից և խուսափել ստեղծած «ստորջրյա խութերից»։
Գոյություն ունեն 3 առավել տարածված փոխակերպումներ՝ տեքստային (տողային), թվային և տրամաբանական:
Տողային փոխակերպումները
կարելի է անել ուղղակիորեն՝String(value)
ֆունկցիայի միջոցով։ Օրինակ՝
String(12); // թվային արժեք 12-ը կվերափոխվի տողային արժեք "12"-ի։
String(true); // Բուլյան արժեք true-ն կվերափոխվի տողային արժեք "true"-ի
Տողային փոխակերպումները լինում են նաև անուղղակի կերպով, երբ ֆունկցիան կամ օպերատորը սպասում են տողային արժեք, սակայն մենք տալիս ենք ուրիշ տիպի արժեք։ Օրինակ alert(value)
ֆունկցիային եթե որպես արժեք տանք թիվ, այն կվերափոխվի տողի։ Կամ եթե տողային արժեքին գումարենք թվային արժեք՝ "2" + 5 == "25": Տեսնելով, որ ձախ կողմի օպերանդը տող է, ինտերպրետատորը ենթադրում է, որ + օպերատորը մենք օգտագործում ենք ոչ թե որպես թվաբանական գումարման օպերատոր, այլ որպես տողերի համակցման (concatenation) օպերատոր, և 5 թվային արժեքը նույնպես վերածում է տողային արժեքի և կատարում տողերի համակցում: Պետք է նշել, որ այդ փոխակերպումը կատարելուց, ինտերպրետատորը խստորեն հետևում է ստանդարտով սահմանված տիպերի փոխակերպումների կանոններին։
Թվային փոխակերպումները
լինում են մաթեմատիկական ֆունկցիաների և արտահայտությունների մեջ։
Օրինակ եթե փորձենք տողերը բաժանել իրար վրա՝ "8" / "2", ապա կստանանք 4, որովհետև հասկանալով որ մենք կատարում ենք թվաբանական գործողություն, ինտերպրետատորը, կրկին հենվելով լեզվական ստանդարտով խստորեն սահմանված կանոններին, փորձում է տողային արժեքը վերածել թվայինի: Մենք կարող ենք այլ տիպի արժեքներից ստանալ թվային արժեք ուղղակիորեն՝ Number(value)
ֆունկցիայի միջոցով։
Կարևոր է հիշել, որ թվային վերափոխման ժամանակ դատարկ տողը վերածվում է 0-ի, եթե տողը դատարկ չէ, սկզբի և վերջի բացատները անտեսվում են, և մնացած մասից փորձ է կատարվում թիվը «կարդալ»։ Եթե հաջողությամբ չի պսակվում, արդյունքը լինում է NaN:
Բուլյան true արժեքը վերածվում է 1-ի, false-ը՝ 0-ի։ Null-ը վերափոխվում է 0-ի, իսկ undefined-ը՝ NaN-ի։
Վերջին վերափոխումը շատ կարևոր է հիշել, որովհետև ամենահաճախն է դառնում սխալների պատճառ։
Բոլոր մաթեմատիկական օպերատորները (միակ բացառությունը + օպերատորն է) տարբեր տիպերի պատկանող արժեքները փորձում են անուղղակիորեն վերածել թվի։
Օրինակ հետևյալ արտահայտության արժեքը կլինի՝
"8" * 3 - null - true; // 23
Կատարվել են անուղղակի փոխակերպումներ,"8"-ը վերածվել է 8-ի, null-ը 0-ի և true-ն 1-ի։
- Ամենահասարակը
տրամաբանական փոխակերպումներն են
։ Դրանք կատարվում են ուղղակիորենBoolean(value)
ֆունկցիայի օգնությամբ, ինչպես նաև անուղղակիորեն՝ օրինակ if else, switch ու մի շարք այլ կոնստրուկցիաների և ցիկլերի պայմանի ստուգման բլոկում։ Փոխակերպման օրինաչափությունը հետևյալն է՝ այն արժեքները, որոնք ինտուիտիվ կերպով «դատարկ» են, վերածվում են false-ի, մնացած բոլորը՝ true են։
falsy արժեքները հետևյալն են՝
- 0
- -0
- 0n (BigInt)
- null
- undefined
- false
- NaN
- "" (դատարկ տող)
Եթե որոշ աղբյուրներում հանդիպեք որ falsy արժեքները 6-ն են, այլ ոչ թե 8-ը, պետք չի զարմանալ, քանի-որ երբեմն -0-ն առանձին չեն նշում, համարելով որ այն նույն 0-ն է և ուղղակի JavaScript-ում թվի ներկայացման այսպես կոչված double-precision 64 բիթային համակարգի օգտագործման տարօրինակ հետևանքը, և որ գործնականում դրա գոյությունը մեծ խնդիրներ չի առաջացնում, թեև մաթեմատիկոսների տեսանկյունից դրա գոյությունն իսկ արդեն տարօրինակություն է: Իսկ BigInt տվյալների տիպը համեմատաբար վերջերս է ավելացել, և առօրյա գործնական խնդիրների մեջ քիչ է օգտագործվում և շատերը միտումնավոր անտեսում կամ մոռանում են, որ լեզվի մեջ այդպիսի նոր տիպ կա:
Բացի այս 8 արժեքից, մնացած բոլոր գոյություն ունեցող արժեքները տիպերի տրամաբանական վերափոխման ժամանակ վերածվում են true-ի, ի դեպ այդ թվում նաև դատարկ զանգվածները կամ օբյեկտները, ինչպես նաև տողը, որն իր մեջ պարունակում է 0 կամ բացատ ("0", " "):
Որպես տիպերի վերափոխման օրինակ, այս հղումով ծանոթացեք մի շատ պատկերավոր աղյուսակի հետ, որտեղ ցուցադրվում է, թե ինչպես է իրեն դրսևորում ոչ խիստ հավասարության օպերատորը == a և b տարբեր տիպերի համար։