Skip to content

Latest commit

 

History

History
109 lines (78 loc) · 10.6 KB

Best Practices for Property Checking in JavaScript.hy.md

File metadata and controls

109 lines (78 loc) · 10.6 KB

Ինչպե՞ս ստուգել, արդյո՞ք տրված հատկությունն առկա է օբյեկտի մեջ: in օպերատորը և hasOwnProperty մեթոդը JavaScript-ում:

Ի տարբերություն մի շարք այլ դասական ծրագրավորման լեզուների՝ JavaScript օբյեկտների առանձնահատկությունը կայանում է նրանում, որ կարելի է մուտք ստանալ օբյեկտի ցանկացած հատկության, և եթե անգամ այդ հատկությունը գոյություն չունի, մենք ոչ թե սխալ կստանանք, այլ undefined:

Օգտագործելով լեզվի այս հատկանիշը՝ մենք հեշտությամբ կարող ենք ստուգել՝ օբյեկտն արդյոք պարունակում է տվյալ հատկությունը թե ոչ։ Օրինակ՝

const car = {
  brand: "BMW",
  color: "red",
};

alert(car.color === undefined); // falses
alert(car.speed === undefined); // true

Վերևի օրինակի մեջ հայտարարում ենք car փոփոխականը, որին որպես արժեք վերագրում ենք օբյեկտ։ (JavaScript-ում օբյեկտային տիպի արժեքները const-ով հայտարարելու դեպքում մենք կարող ենք հեշտությամբ փոփոխել նրանց ներքին կառուցվածքը, ավելացնել կամ ջնջել հատկություններ և մեթոդներ, սակայն մենք չենք կարող նոր վերագրում կատարել, այդ իսկ պատճառով ցանկալի է օբյեկտային տիպ ստեղծելուց օգտվել հաստատունից՝ const-ից, քանի-որ դա թույլ կտա զգալիորեն քչացնել հավանական սխալների քանակը և կհեշտացնի սխալների ուղղումը՝ դեբագգինգը

Երբ ուզում ենք ստուգել թե car օբյեկտը արդյո՞ք պարունակում է color հատկությունը, մենք ընդամենը կատարում ենք խիստ համեմատություն undefined-ի հետ։ Եթե օբյեկտում կա color հատկությունը, ապա այն կվերադարձնի false, իսկ եթե հատկությունը այնտեղ բացակայում է, ապա խիստ համեմատության օպերատորը (===) կվերադարձնի true:

Օբյեկտի մեջ հատկության առկայության ստուգման այս եղանակը դեպքերի ճնշող մեծամասնության դեպքում հրաշալի աշխատում է։ Սակայն կա մի խնդիր։ Ընդհանրապես ընդունված է, որ փոփոխականներին կամ օբյեկտի հատկություններին դատարկ կամ գոյություն չունեցող արժեք վերագրելիս օգտագործել null-ը, սակայն JavaScript-ը ոչ մի արգելք չի հարուցում, որ մենք փոփոխական կամ օբյեկտի հատկություն ստեղծենք ու նրան վերագրենք undefined: Այս դեպքում վերը նշված եղանակով ստուգումը կարող է թյուրիմացության պատճառ դառնալ, օրինակ՝

const car = {
  brand: "BMW",
  color: "red",
  speed: undefined,
};

alert(car.speed === undefined); // true

Ստացվում է, որ այս ստուգման արդյունքներով մենք կարող ենք եզրակացնել, թե car օբյեկտում չկա speed հատկությունը, այնինչ այդ հատկությունը կա, ուղղակի նրան վերագրվել է undefined, ինչը լեզվական ոչ մի կանոն չի խախտում, լեզվի ճկունությունը դա թույլ է տալիս, սակայն խորհուրդ չի տրվում այդպես անել։

Ավելի կոռեկտ արդյունք ունենալու համար մենք կարող ենք օգտագործել in օպերատորը։ Այն վերադարձնում է true, եթե տվյալ հատկությունը պարունակվում է օբյեկտի կամ նրա պրոտոտիպերի շղթայի մեջ։ Սինթաքսն ունի հետևյալ տեսքը՝

  • prop in object

որտեղ prop-ը դա իրենից ներկայացնում է հատկության անունը կամ զանգվածի ինդեքսը և կարող է լինել միայն String կամ Symbol տիպի։ Եթե այն չի պատկանում վերը նշված այդ երկու տիպերից որևէ մեկին, ապա այնուամենայնիվ անուղղակի վերափոխվում է String տիպի։

object-ը դա այն օբյեկտն է, որի մեջ պատրաստվում ենք ստուգել, թե կա արդյոք տրված անունով հատկությունը։

const car = {
  brand: "BMW",
  color: "red",
  speed: undefined,
};

alert("brand" in car); // true
alert("speed" in car); // true
alert("isExpensive" in car); // false

Եվ այսպես car օբյեկտը պարունակում է "brand" հատկությունը, հետևաբար in օպերատորը վերադարձնում է true: Այն պարունակում է նաև "speed" հատկությունը, թեև նրան մենք վերագրել ենք undefined, և in օպերատորը կրկին կվերադարձնի true, իսկ եթե մենք ստուգումը կատարեյինք առաջին եղանակով՝ խիստ հավասարության օպերատորի օգնությամբ համեմատելով undefined-ի հետ, մենք կարող էինք սխալ եզրահանգման գալ, որ car օբյեկտի մեջ գոյություն չունի "speed" հատկություն։

Ուշադրություն դարձնենք այն բանի վրա, որ in օպերատորով ստուգում կատարելիս ՊԱՐՏԱԴԻՐ պետք է հատկության անունը գրենք չակերտների մեջ։ Ինչպես գիտենք օբյեկտի հատկությունները կարող են լինել միայն String և Symbol տիպի։ Օբյեկտի մեջ հատկության String տիպին պատկանելու դեպքում մենք կարող ենք այդ չակերտները բաց թողել, դա JavaScript-ի սինթաքսը թույլ է տալիս, և հիմնականում այդպես էլ անում ենք։ Սակայն չպետք է մոռանալ, որ դա այնուամենայնիվ String է, և in օպերատորի հետ օգտագործելու ժամանակ պարտադիր պետք է չակերտներն օգտագործվեն։ Հակառակ դեպքում լեզվի ինտերպրետատորը մտածում է, որ մենք այդ անունով փոփոխական ունենք, որին վերագրել ենք օբյեկտի հատկության անունը, և փորձելով գտնել այդ փաստացի չհայտարարված փոփոխականը, տալիս է ReferenceError:

Այս տարբերակով կլինի կոռեկտ՝

const car = {
  brand: "BMW",
  color: "red",
  speed: undefined,
};

let brand = "brand";
brand in car; // true

Զանգվածի մեջ in օպերատորի օգնությամբ կարող ենք որոշել, թե արդյոք համապատասխան ինդեքսը գոյություն ունի թե ոչ։ Օրինակ՝

const cars = ["BMW", "Volvo", "Porsche"];
alert(0 in cars); // true
alert("2" in cars); // true
alert(3 in cars); // false

Ինչպես տեսնում ենք զանգվածի մեջ տվյալ ինդեքսի առկայության դեպքում in օպերատորը վերադարձնում է true, բացակայության դեպքում՝ false: Նաև ուշադրություն դարձրեք, որ ինդեքսը ստուգելուց` այն չակերտների մեջ վերցնել պարտադիր չէ, երբ մենք այն բաց ենք թողնում, տակից այդ վերափոխությունն այնուամենայնիվ կատարվում է։ in օպերատորն ունի մի շատ հետաքրքիր հատկություն։ Այն ստուգում է տրված հատկության պարունակությունը օբյեկտում և այդ հատկության բացակայության դեպքում պրոտոտիպերի շղթայում շարունակում է ստուգել մինչև շղթայի ծայրը։ Այսինքն այս օպերատորը ստուգում կատարելիս ժառանգվող հատկությունների համար նույնպես վերադարձնում է "true": Դիտարկենք հետևյալ օրինակը՝

const car = {
  brand: "BMW",
  color: "red",
  speed: undefined,
};

alert("toString" in car); // true

Ինչպես տեսնում ենք մեր օբյեկտի մեջ չկա toString մեթոդը, սակայն in օպերատորը մեզ վերադարձնում է true: Այսինքն օբյեկտի մեջ չգտնելով "toString"-ը, նա պրոտոտիպերի շղթայով բարձրացել է վերև և գտել է այս ներդրված մեթոդը, որը մեր ստեղծած օբյեկտը ժառանգել է։

Շատ հաճախ մեզ անհրաժեշտ է լինում ստուգել օբյեկտի մեջ հատկության առկայությունը, սակայն առանց պրոտոտիպերի շղթայով վերև բարձրանալու։ Այդ դեպքում մենք պետք է օգտագործենք hasOwnProperty մեթոդը։ Օրինակ՝

const car = {
  brand: "BMW",
  color: "red",
  speed: undefined,
};

alert(car.hasOwnProperty("color")); // true
alert(car.hasOwnProperty("speed")); // true
alert(car.hasOwnProperty("toString")); // false

Ինչպես տեսնում ենք hasOwnProperty մեթոդը բոլորովին հաշվի չի առնում պրոտոտիպերի շղթայից ժառանգված հատկություններն ու մեթոդները։ Այս եղանակներից ո՞րն օգտագործել, կախված է խնդրի բնույթից, բայց մեծամասամբ ավելի անվտանգ է hasOwnProperty մեթոդը։ Մեթոդի մասին ավելի մանրամասն կարող եք ծանոթանալ այս հղումով։