Դինամիկ տիպի նույնականացում
Դինամիկ տիպի նույնականացում (RTTI)թույլ է տալիս որոշել օբյեկտի տեսակը գործարկման ժամանակ: Պարզվում է, որ այն օգտակար է մի շարք պատճառներով. Մասնավորապես, հղում կատարելով բազային դասին, դուք կարող եք բավականին ճշգրիտ որոշել այս հղումով հասանելի օբյեկտի տեսակը: Դինամիկ տիպի նույնականացումը թույլ է տալիս նաև նախապես ստուգել, թե որքանով կհաջողվի տիպի ձուլման արդյունքը՝ կանխելով բացառությունը սխալ տեսակի ձուլման պատճառով: Բացի այդ, դինամիկ տիպի նույնականացումը արտացոլման հիմնական բաղադրիչն է:
Դինամիկ տիպի նույնականացումն աջակցելու համար C#-ը տրամադրում է երեք հիմնաբառերա. է, ինչպես և տեսակը: Այս հիմնաբառերից յուրաքանչյուրը հաջորդաբար քննարկվում է:
օպերատոր է
Օբյեկտի հատուկ տեսակը կարելի է որոշել՝ օգտագործելով is օպերատորը: Ստորև ներկայացնում ենք դրա ընդհանուր ձևը.
արտահայտությունը տեսակ է
որտեղ արտահայտությունը նշանակում է մեկ արտահայտություն, որը նկարագրում է այն օբյեկտը, որի տեսակը փորձարկվում է: Եթե արտահայտությունը համապատասխանում է կամ նույն տեսակին է, ինչ փորձարկվող տեսակը, ապա այս գործողության արդյունքը ճշմարիտ է, հակառակ դեպքում՝ կեղծ: Այսպիսով, արդյունքը ճշմարիտ կլինի, եթե արտահայտությունը այս կամ այն ձևով փորձարկվող տեսակին է: Is-ի օպերատորում երկու տեսակներն էլ սահմանվում են որպես համատեղելի, եթե դրանք նույն տիպն են, կամ եթե ապահովված է տեղեկանքի փոխակերպում, բոքսինգ կամ ապաբոքսավորում:
Հետևյալը is օպերատորի օգտագործման օրինակ է.
Համակարգի օգտագործում; namespace ConsoleApplication1 ( class Add ( ) class Sum. Add ( ) class Program ( static void Main() ( Add a = new Add(); Sum s = new Sum(); if (a is Add) Console.WriteLine("Variable a-ն տիպի է Add"); if (s-ը Sum է) Console.WriteLine ("S փոփոխականի տեսակը ժառանգված է Add դասից"); Console.ReadLine(); ) ) )
որպես օպերատոր
Երբեմն տիպի փոխարկումը պետք է կատարվի գործարկման ժամանակ, բայց բացառություն չանելու համար, եթե փոխարկումը ձախողվի, ինչը միանգամայն հնարավոր է տիպի cast-ի դեպքում: As օպերատորը ծառայում է այս նպատակին և ունի հետևյալ ընդհանուր ձևը.
արտահայտությունը որպես տեսակ
որտեղ արտահայտությունը նշանակում է մեկ արտահայտություն, որը փոխարկելի է նշված տեսակին:
Եթե նման փոխակերպման արդյունքը հաջող է, ապա տիպի հղումը վերադարձվում է, հակառակ դեպքում՝ զրոյական հղում: As օպերատորը կարող է օգտագործվել միայն հղման փոխակերպման, ինքնության, բռնցքամարտի, ապաարկղացման համար: Որոշ դեպքերում as օպերատորը կարող է հարմար այլընտրանք լինել is օպերատորին: Որպես օրինակ, դիտարկեք հետևյալ ծրագիրը.
Համակարգի օգտագործում; namespace ConsoleApplication1 ( class Add ( ) class Sum. Add ( ) class Program ( static void Main() ( Add a = new Add(); Sum s = new Sum(); // Կատարել cast a = s որպես Add; if ( a != null) Console.WriteLine («Փոխակերպումը հաջողվեց»); else Console.WriteLine («Սխալ փոխակերպման ժամանակ»); Console.ReadLine (); ) ) )
Այս ծրագրի կատարման արդյունքը կլինի հաջող փոխակերպում:
JavaScriptկամ JS(կարճ) հեշտ լեզու չէ, և սկսնակ մշակողները անմիջապես չեն իմանա դրա մասին: Սկզբում նրանք սովորում են հիմունքները, և ամեն ինչ թվում է գունեղ ու գեղեցիկ: Մի փոքր խորանալով՝ կան JavaScript զանգվածներ, առարկաներ, հետզանգեր և մնացած ամեն ինչ, որը հաճախ խելք է տալիս:
JavaScript-ում կարևոր է ճիշտ ստուգել փոփոխականի տեսակը: Ենթադրենք, դուք ուզում եք իմանալ, թե արդյոք զանգվածի փոփոխականկամ առարկա. Ինչպե՞ս ճիշտ ստուգել: Կոնկրետ այս դեպքում ստուգման ժամանակ հնարքներ կան և հենց դրա մասին է լինելու այս գրառումը։ Եկեք անմիջապես սկսենք:
Փոփոխականի տեսակի ստուգում
Օրինակ, դուք պետք է ստուգեք՝ արդյոք փոփոխականը օբյեկտ է, զանգված, տող կամ թիվ։ Դուք կարող եք օգտագործել typeof-ը դրա համար, բայց դա միշտ չէ, որ ձեզ կասի ճշմարտությունը, և ես ձեզ ցույց կտամ, թե ինչու ստորև բերված օրինակում:
Ես գրել եմ այս օրինակը, որպեսզի բացատրեմ, թե ինչու է typeof-ը ոչ միշտ ճիշտ ընտրությունը:
Var _comparison = ( տող՝ «string», int՝ 99, float՝ 13.555, օբյեկտ՝ (բարև՝ «բարև»), զանգված՝ new Array(1, 2, 3) ); // Վերադարձնում է զանգված՝ օբյեկտի ստեղներով var _objKeys = Object.keys(_comparison); for(var i = 0; i<= _objKeys.length - 1; i++) { // выведем в консоль тип каждой переменной console.log(typeof _comparson[_objKeys[i]]); }
Կոդի կատարման արդյունքը.
Տողային համարի օբյեկտ
Ճիշտ? - Իհարկե ոչ. Երկու խնդիր կա. Դրանցից յուրաքանչյուրը մանրամասն նկարագրված կլինի և կառաջարկվի լուծում:
Առաջին խնդիր՝ լողացող համար, ելք՝ որպես թիվ
Comparison.float-ը թիվ չէ և թվի փոխարեն պետք է լինի float: Դա շտկելու համար կարող եք ստեղծել ֆունկցիա՝ ստորև նշված կոդի նման ստուգմամբ:
Var_floatNumber = 9.22; var_notFloatNumber = 9; console.log(isFloat(_floatNumber)); console.log(isFloat(_notFloatNumber)); console.log (isFloat ("")); ֆունկցիան isFloat(n)( վերադարձ Թիվ(n) === n && n % 1 !== 0;)
isFloat() ֆունկցիան ստուգում է բոլոր արժեքները լողացող կետերի համարների համար: Նախ ստուգեք՝ արդյոք փոփոխականը հավասար է nթիվ (թիվ (n) === n) և եթե այո, ապա ևս մեկ ստուգում է կատարվում մնացորդով բաժանելու համար, իսկ եթե կա մնացորդ, ապա վերադարձվում է բուլ ( ճիշտկամ կեղծ) արդյունք (n % 1 !== 0):
Վերևի օրինակում այն վերադառնում է ճիշտ, կեղծև կեղծ. Առաջին իմաստն է լողալտեսակը, երկրորդը ոչ. սա սովորական թիվ է, իսկ վերջինը պարզապես դատարկ տող է, որը չի համապատասխանում կանոններին:
Երկրորդ խնդիրը. զանգվածը սահմանվել է որպես օբյեկտ
Առաջին իսկ օրինակում զանգվածը ներկայացվում է որպես օբյեկտ, ինչը այնքան էլ լավ չէ, քանի որ երբեմն անհրաժեշտ է օգտագործել այս տեսակը և ուրիշ ոչինչ:
Զանգվածի տեսակի համար փոփոխականը փորձարկելու մի քանի եղանակ կա:
Առաջին տարբերակը (լավ տարբերակ): Ստուգեք, արդյոք տվյալները պատկանում են զանգվածին, օգտագործելով instanceof():
Var data = new Array («բարև», «աշխարհ»); var isArr = Array-ի տվյալների օրինակ;
Երկրորդ տարբերակը (լավ տարբերակ): Array.isArray() մեթոդը վերադարձնում է բուլյան արժեք, որը կախված կլինի նրանից, թե արդյոք փոփոխականը զանգված է, թե ոչ ():
Var data = new Array («բարև», «աշխարհ»); var isArr = Array.isArray (տվյալներ);
Երրորդ տարբերակը (լավագույնը, բայց երկար): Հարմարության համար դուք կարող եք այս մեթոդը դարձնել գործառույթ: Օբյեկտի օգնությամբ մենք պատրաստում ենք. Եթե Object.prototype.toString.call(data)-ի արդյունքը հավասար չէ, ապա փոփոխականը զանգված չէ ():
Var data = new Array («բարև», «աշխարհ»); var isArr = Object.prototype.toString.call(data) == ""; console.log (isArr);
Վերջին արդյունքը որպես հարմարության գործառույթ.
Ֆունկցիան isArray(տվյալներ) ( վերադարձնել Object.prototype.toString.call(data) == "" )
Այժմ կարող եք կանչել isArray() ֆունկցիաները և որպես արգումենտ սահմանել զանգված կամ որևէ այլ բան և տեսնել արդյունքը:
Հետբառ
Ռեկորդը բավականին մեծ է ստացվել, քան ի սկզբանե նախատեսված էր։ Բայց ես գոհ եմ դրանով, քանի որ այն բավականաչափ հակիրճ և պարզ է՝ նկարագրելու JavaScript-ում փոփոխականների վավերացման դժվարությունները և ինչպես շրջանցել դրանք:
Եթե ունեք հարցեր, խնդրում ենք դրանք տեղադրել այս գրառման տակ: Ես ուրախ կլինեմ օգնել:
a = (b > 0) && (c + 1 != d); դրոշ = !(կարգավիճակ = 0);
Աղյուսակ 14.5. Տրամաբանական օպերատորներ
Օպերատորի նկարագրությունը
! ՉԻ (տրամաբանական շրջադարձ)
&& ԵՎ (բուլյան բազմապատկում)
|| ԿԱՄ (տրամաբանական հավելում)
Աղյուսակ 14.6. AND և OR օպերատորների կատարման արդյունքները
Օպերանդ 1 |
Օպերանդ 2 |
||
Աղյուսակ 14.7. NOT հայտարարության կատարման արդյունքները
ստանալ օպերատորի տեսակը
Ստացեք տիպի օպերատոր typeof-ը վերադարձնում է տող, որը նկարագրում է օպերանդի տվյալների տեսակը: Օպերանդը, որի տեսակը պետք է գտնել, տեղադրվում է այս օպերատորից հետո և փակվում է փակագծերում.
s = typeof ("str");
Այս արտահայտության արդյունքում s փոփոխականը կպարունակի «string» տողը, որը նշանակում է տողի տեսակը:
Բոլոր արժեքները, որոնք կարող է վերադարձնել օպերատորի տեսակը, թվարկված են Աղյուսակ 1-ում: 14.8.
Աղյուսակ 14.8. Օպերատորի տեսակի կողմից վերադարձված արժեքներ |
||
Տվյալների տեսակը |
Վերադարձի տողը |
|
Լարային |
||
Թվային |
||
Աղյուսակ 14.8 (վերջ) |
|||
Տվյալների տեսակը |
Վերադարձի տողը |
||
Տրամաբանական |
|||
Համատեղելիություն և տվյալների տիպի փոխակերպում
Ժամանակն է դիտարկել ևս երկու կարևոր խնդիր՝ տվյալների տիպի համատեղելիությունը և փոխակերպումը մի տեսակից մյուսը:
Ի՞նչ է տեղի ունենում, երբ երկու թիվ գումարում եք իրար: Ճիշտ է, ևս մեկ թվային արժեք: Իսկ եթե ավելացնեք թիվ և տող: Դժվար է ասել... Այստեղ JavaScript-ը հանդիպում է տվյալների տիպերի անհամատեղելիության խնդրին և փորձում է այս տեսակները համատեղելի դարձնել՝ դրանցից մեկը փոխակերպելով մյուսի։ Այն նախ փորձում է տողը վերածել թվի և, եթե հաջողվի, կատարում է գումարում։ Եթե չհաջողվի, թիվը կվերածվի տողի, և ստացված երկու տողերը կմիացվեն: Օրինակ, 14-6 ցուցակում գտնվող վեբ սկրիպտը կվերափոխի b փոփոխականի արժեքը, երբ ավելացվի a փոփոխականին թվային տիպի; Այսպիսով, c փոփոխականը կպարունակի 23 արժեքը:
Ցուցակ 14.6
var a, b, c, d, e, f; a = 11;
b = «12»; c = a + b;
d = "JavaScript"; e = 2;
Բայց քանի որ d փոփոխականի արժեքը չի կարող փոխարկվել թվի, e-ի արժեքը կվերածվի տողի, իսկ արդյունքը՝ f-ի արժեքը հավասար կլինի
Բուլյան արժեքները, ըստ անհրաժեշտության, փոխարկվում են կամ թվային կամ լարային արժեքների: True-ը կվերածվի 1 թվի կամ «1» տողի, իսկ false-ը՝ 0-ի կամ «0»-ի: Ընդհակառակը, 1 թիվը կվերածվի ճշմարիտի, իսկ 0 թիվը՝ կեղծ: Նաև կեղծը կվերածվի
մենք զրոյական և անորոշ ենք:
Մաս III. Վեբ էջի վարքագիծը. Վեբ սցենարներ |
|
Կարելի է տեսնել, որ JavaScript-ը դժվարանում է ճիշտ կատարել նույնիսկ սխալ գրված արտահայտությունները: Երբեմն դա աշխատում է, բայց ավելի հաճախ, քան ոչ, ամեն ինչ չի ստացվում այնպես, ինչպես պլանավորված էր, և, ի վերջո, վեբ սցենարը ընդհատվում է սխալի պատճառով, որը հայտնաբերվել է սցենարի բոլորովին այլ տեղում, բացարձակապես ճիշտ հայտարարության վրա: Ուստի ավելի լավ է խուսափել նման միջադեպերից։
Օպերատորի գերակայություն
Վերջին խնդիրը, որով մենք կզբաղվենք այստեղ, օպերատորի գերակայությունն է: Ինչպես հիշում ենք, գերակայությունը ազդում է արտահայտության օպերատորների կատարման հերթականության վրա:
Թող լինի հետևյալ արտահայտությունը.
Այս դեպքում նախ c-ի արժեքը կավելացվի b փոփոխականի արժեքին, իսկ հետո գումարից կհանվի 10-ը։Այս արտահայտության օպերատորներն ունեն նույն գերակայությունը և հետևաբար կատարվում են խիստ ձախից աջ։
Այժմ հաշվի առեք այս արտահայտությունը.
Այստեղ նախ c արժեքը կբազմապատկվի 10-ով, և միայն դրանից հետո b արժեքը կավելացվի ստացված արտադրյալին։ Բազմապատկման օպերատորն ավելի մեծ գերակայություն ունի, քան գումարման օպերատորը, ուստի «խիստ ձախից աջ» կարգը կխախտվի:
Հանձնարարությունների օպերատորներն ունեն ամենացածր գերակայությունը: Դրա համար սկզբում գնահատվում է ինքնին արտահայտությունը, իսկ հետո դրա արդյունքը վերագրվում է փոփոխականին։
Վ Ընդհանուր առմամբ, բոլոր հայտարարությունների կատարման հիմնական սկզբունքը հետևյալն է. նախ՝ ավելի քան հայտարարություններ բարձր առաջնահերթություն, և միայն դրանից հետո՝ ավելի ցածր օպերատորներ։ Նույն գերակայությամբ օպերատորները գործարկվում են այն հերթականությամբ, որով նրանք հայտնվում են (ձախից աջ):
Վ ներդիր. 14.9-ում թվարկված են բոլոր այն օպերատորները, որոնք մենք ուսումնասիրել ենք՝ ըստ իրենց առաջնահերթության նվազման կարգով:
Աղյուսակ 14.9. Օպերատորի գերակայություն (նվազման կարգով) |
||
Օպերատորներ |
Նկարագրություն |
|
++ -- - ~ ! տեսակ |
Աճում, նվազում, նշանի փոփոխություն, տրամաբանական ՈՉ, տիպի եզրակացություն |
|
Բազմապատկում, բաժանում, մնացորդ |
||
Լարի գումարում և միացում, հանում |
||
Համեմատության օպերատորներ |
||
տրամաբանական ԵՎ |
||
Գլուխ 14. Վեբ ծրագրավորման ներածություն. JavaScript լեզու |
|||
Աղյուսակ 14.9 (վերջ) |
|||
Օպերատորներ |
Նկարագրություն |
||
Տրամաբանական ԿԱՄ |
|||
Պայմանական օպերատոր (տես ստորև) |
|||
= <оператор>= |
Առաջադրանք՝ պարզ և բարդ |
||
ՈՒՇԱԴՐՈՒԹՅՈՒՆ.
Հիշեք այս աղյուսակը. Հայտարարությունների կատարման սխալ հերթականությունը կարող է առաջացնել դժվար հայտնաբերվող սխալներ, որոնցում, ըստ երևույթին, բացարձակապես ճիշտ արտահայտությունը տալիս է սխալ արդյունք:
Բայց ի՞նչ, եթե մեզ անհրաժեշտ լինի խախտել հայտարարությունների կատարման սովորական կարգը: Օգտագործենք փակագծեր։ Այս նշման մեջ նախ կատարվում են փակագծերում դրված հայտարարությունները.
a = (b + c) * 10;
Այստեղ սկզբում կավելացվեն b և c փոփոխականների արժեքները, իսկ հետո ստացված գումարը կբազմապատկվի 10-ով:
Փակագծերում փակցված օպերատորները նույնպես ենթակա են գերակայության: Հետևաբար, հաճախ օգտագործվում են բազմակի տեղադրված փակագծեր.
a = ((բ + գ) * 10 - դ) / 2 + 9;
Այստեղ հայտարարությունները կկատարվեն հետևյալ հաջորդականությամբ.
1. Ավելացնել b և c.
2. Ստացված գումարը բազմապատկեք 10-ով։
3. Արտադրանքից հանելով դ.
4. Տարբերությունը բաժանեք 2-ի։
5. 9-ի գումարում գործակիցին:
Եթե հանում եք փակագծերը.
a = b + c * 10 - d / 2 + 9;
ապա օպերատորների կատարման կարգը կլինի հետևյալը.
1. Բազմապատկել c-ը և 10-ը:
2. d-ը բաժանեք 2-ի:
3. Բ գումարելն ու c-ն ու 10-ը բազմապատկելը։
4. Բաժանման գործակիցի ստացված գումարից հանումդ-ից 2.
5. Ստացված տարբերությանը ավելացնելով 9:
Բոլորովին այլ արդյունք է ստացվում, չէ՞։
- undefined: «չսահմանված»
- Null՝ «օբյեկտ»
- Բուլյան: «բուլյան»
- Համար՝ «համար»
- Տող՝ «լար»
- Գործառույթ՝ «գործառույթ»
- Մնացած ամեն ինչ՝ «օբյեկտ»
Այս աղյուսակին պետք է ավելացնել հետևյալ դիտողությունները.
1. typeof null === «օբյեկտ» .
Տեսականորեն այստեղ կա մի նուրբ կետ. Ստատիկ տպագրված լեզուներում օբյեկտի տիպի փոփոխականը կարող է օբյեկտ չպարունակել (NULL, զրոյական, զրոյական ցուցիչ):
Գործնականում JavaScript-ում դա անհարմար է: Այսպիսով, ES 5.1 մշակողները պատրաստվում են անել ավելի ինտուիտիվ մի բան՝ typeof null === «null»:
Բայց քանի որ մենք դեռ ES3-ի շուրջ ենք, մի սխալվեք, օրինակ, այս հարցում.
/* Ֆունկցիան որոնում է ինչ-որ օբյեկտ և վերադարձնում է այն կամ զրոյացնում, եթե ոչինչ չի գտնվել */ search function() () var obj = search(); if (տիպի obj === «օբյեկտ») ( // մենք իսկապես գտանք օբյեկտը (FAIL) obj.method(); )
2. Մի մոռացեք փաթաթվող օբյեկտների մասին (նոր համարի տեսակը(5) === «օբյեկտ»):
3. Եվ մի մոռացեք բրաուզերների՝ հոսթ-օբյեկտների հետ որևէ բան անելու իրավունքը։
Մի զարմացեք, որ Safari-ն համառորեն վերաբերվում է HTMLCollection-ին որպես ֆունկցիայի տեսակի, իսկ մինչ 9-րդ IE-ը պահպանում է մեր սիրելի alert() ֆունկցիան որպես օբյեկտ: Բացի այդ, Chrome-ը RegExp-ը համարում էր ֆունկցիա, բայց հիմա կարծես թե ուշքի է գալիս և դրան արձագանքում է օբյեկտով:
toString ()
Նրա toString() մեթոդի արդյունքից արժեքի տեսակը պարզելն անիմաստ է։ Բոլոր «դասերում» այս մեթոդը վերաիմաստավորվում է իր համար:
Մեթոդը լավ է վրիպազերծման տեղեկատվությունը ցուցադրելու համար, սակայն փոփոխականի տեսակը չի կարող որոշվել դրանից:
Object.prototype.toString()
Թեև toString-ը վերացված է կոնկրետ «դասերի» ներսում, մենք դեռ ունենք դրա սկզբնական իրականացումը Object-ից: Փորձենք օգտագործել այն.
console.log (Object .prototype .toString .call (արժեք) ); |
console.log (Object.prototype.toString.call(արժեք));
Քլինթոնը թուլացնում է այս բեռը
Տարօրինակ կերպով, այս մեթոդը զարմանալիորեն լավ է աշխատում:
Համար սկալյար տեսակներվերադառնում է , , , .
Զավեշտալին այն է, որ նույնիսկ նոր համարը (5), որի վրա ձախողված տիպն այստեղ վերադառնում է:
Չեղյալ և չսահմանված դեպքում մեթոդը չի հաջողվի: Տարբեր բրաուզերներ վերադառնում են կամ սպասված և, կամ, կամ նույնիսկ: Այնուամենայնիվ, առանց դրա հեշտ է որոշել այս երկու արժեքների տեսակը:
Հետաքրքիրը սկսվում է այն ժամանակ, երբ մենք հասնում ենք օբյեկտներին (տիպի === «օբյեկտ» ունեցողներին):
Ներկառուցված առարկաները գործնականում աշխատում են պայթյունով.
- {} —
- —
- ամսաթիվ-
- սխալ-
- regexp-
Միակ բանը, որը դուրս է գալիս փաստարկների ցանկից, որը կամ , կամ .
Հոսթ-օբյեկտների դեպքում ամեն ինչ նորից ավելի վատ է:
IE-ում DOM օբյեկտները սկսեցին դառնալ «նորմալ» օբյեկտներ միայն 8-րդ տարբերակից, այնուհետև ոչ այնքան մինչև վերջ: Հետևաբար, IE 6-8-ում այս բոլոր օբյեկտները (HTMLCOllection, DOMElement, TextNode, ինչպես նաև փաստաթուղթ և պատուհան) պարզապես փոխանցվում են .
Բոլոր մյուս բրաուզերներում (ներառյալ IE9), դուք արդեն կարող եք ինչ-որ բան անել toString արդյունքի հետ: Չնայած ամեն ինչ նույնպես հեշտ չէ. HTMLCollection այնտեղ, ապա . պատուհան - հետո, հետո, հետո: Բայց դուք արդեն կարող եք փորձել ինչ-որ բան ստանալ սրանից:
DOMElement-ի հետ ավելի դժվար է. այն ցուցադրվում է որպես , տարբեր ձևաչափով յուրաքանչյուր պիտակի համար: Բայց այստեղ մեզ կօգնի կանոնավոր առաջնությունը։
Այլ հյուրընկալող օբյեկտների դեպքում (տեղորոշման և նավիգատորի թեստերում) պատմությունը մոտավորապես նույնն է: Ամենուր, բացի IE-ից, դրանք կարող են նույնականացվել տողի միջոցով:
Object.prototype.toString() օգտագործման թերություններից:
1. Այս հնարավորությունը չի օծվում ստանդարտով: Եվ մենք այստեղ ավելի շուտ պետք է ուրախանանք, որ ամեն ինչ այդքան լավ է ստացվում, այլ ոչ թե ողբալ որոշ թերությունների համար։
2. Տեսակ որոշելը վերլուծելով տողը, որը վերադարձվել է մի մեթոդով, որն ամենևին էլ տեսակը որոշելու համար չէ, և նույնիսկ կանչվել է այն առարկայի վրա, որի վրա այն չի կիրառվում, որոշակի նստվածք է թողնում հոգու վրա:
3. Հին IE-ում, ինչպես տեսնում եք, հոսթ-օբյեկտները սովորաբար չեն նույնացվում:
Այնուամենայնիվ, դա բավականին աշխատող բան է, երբ օգտագործվում է այլ գործիքների հետ միասին:
Կոնստրուկտորներ
Եվ վերջապես, կոնստրուկտորներ. Ո՞վ ավելի լավ կարող է ասել JS-ում օբյեկտի «դասի» մասին, քան դրա կոնստրուկտորը:
null-ը և undefined-ը չունեն ոչ wrapper օբյեկտներ, ոչ էլ կառուցողներ:
Մնացած սկալարի տեսակներն ունեն փաթաթիչներ, այնպես որ կարող եք ստանալ կոնստրուկտոր.
(5) .կոնստրուկտոր === Համար ; (Թիվ .NaN ) .կոնստրուկտոր === Համար ; (ճշմարիտ ) .կոնստրուկտոր === Բուլյան ; ("string") .constructor === String ; |
(5).կոնստրուկտոր === Համար; (Number.NaN).constructor === Համար; (ճշմարիտ).կոնստրուկտոր === Բուլյան; ("string").constructor === Տող;
Բայց օրինակը այստեղ չի աշխատի.
5 օրինակ համարի; // false Number .NaN համարի օրինակ ; // Բուլյան կեղծ ճշմարիտ օրինակ; // false "string" instance of String ; // կեղծ |
5 օրինակ համարի; // false Number.NaN օրինակ Number; // Բուլյան կեղծ ճշմարիտ օրինակ; // String-ի կեղծ «string» օրինակ; // կեղծ
(օրինակը կաշխատի նոր բազմաչարչար համարի համար (5))
Գործառույթների հետ (որոնք նույնպես օբյեկտներ են), instanceof-ը կանի.
տեղեկամատյան ( (function () ( ) ) instanceof Function ) ; // true console.log ((function () () ) .constructor === Function ) ; // ճիշտ |
console.log ((function () ()) instanceof Function); // true console.log((function () ()).constructor === Function); // ճիշտ
Ներկառուցված դասերի բոլոր օբյեկտները նույնպես հեշտությամբ նույնականացվում են կոնստրուկտորների կողմից՝ Array, Date, RegExp, Error:
Այստեղ մեկ խնդիր է առաջանում արգումենտների հետ, որոնց կոնստրուկտորը Object է:
Եվ երկրորդը՝ հենց Օբյեկտի հետ, ավելի ճիշտ՝ ինչպես կարելի է դրան վերաբերել հատուկ կոնստրուկտորի միջոցով ստեղծված օբյեկտին:
Միայն հիմնական օբյեկտը կարող է սահմանվել այսպես.
Օբյեկտի օրինակ;
Որպես սահմանման տարբերակներից մեկը, կրկնեք բոլոր հնարավոր տեսակների վրա (Array, Error…) և եթե դրանցից ոչ մեկը չի ընկնում «օբյեկտ» տակ։
Կոնստրուկտորներ և հյուրընկալող օբյեկտներ
Ամեն ինչ վատանում է հյուրընկալող օբյեկտների հետ:
Սկսենք նրանից, որ IE-ն մինչև 7-րդ տարբերակը ներառյալ դրանք ամենևին էլ նորմալ օբյեկտներ չի համարում։ Նրանք այնտեղ պարզապես կոնստրուկտորներ ու նախատիպեր չունեն (ամեն դեպքում ծրագրավորողը չի կարող հասնել դրանց)։
Այլ բրաուզերներում ամեն ինչ ավելի լավ է: Կան կոնստրուկտորներ, և դրանցից կարելի է որոշել արժեքի դասը: Միայն դրանք տարբեր բրաուզերներում տարբեր կերպ են կոչվում: Օրինակ, HTMLCollection-ի համար կոնստրուկտորը կլինի կամ HTMLCollection կամ NodeList, կամ նույնիսկ NodeListConstructor:
Դուք նաև պետք է սահմանեք DOMElement-ի բազային կոնստրուկտոր: FF-ում սա, օրինակ, HTMLElement-ն է, որից HTMLDivElement-ը և մյուսներն արդեն ժառանգում են:
Հնարքը նետված է FireFox-ի կողմից 10-րդ տարբերակից ներքև, իսկ Opera-ն՝ 11-րդ տարբերակից: Այնտեղ հավաքածուի կառուցողը Object-ն է:
կոնստրուկտոր.անուն
Կոնստրուկտորներն ունեն նաև անվանման հատկություն, որը կարող է օգտակար լինել:
Այն պարունակում է կոնստրուկտոր ֆունկցիայի անունը, օրինակ՝ (5).constructor.name === «Թիվ» .
Բայց.
1. IE-ում դա ընդհանրապես չէ, նույնիսկ 9-րդում։
2. Host-objects-ում բրաուզերները կրկին ձևավորում են այն ամենը, ինչ շատ է (և հաճախ նրանք ընդհանրապես չունեն այս հատկությունը): Opera-ում DOMElement-ն ունի կոնստրուկտորի անուն ընդհանուր առմամբ Function.prototype:
3. կրկին փաստարկներ «օբյեկտ».
եզրակացություններ
Ներկայացված մեթոդներից և ոչ մեկը չի տալիս 100% սահմանում արժեքի տեսակի / դասի բոլոր բրաուզերներում: Այնուամենայնիվ, նրանք միասին թույլ են տալիս դա անել:
Մոտ ապագայում ես կփորձեմ հավաքել բոլոր տվյալները աղյուսակներում և բերել որոշիչ ֆունկցիայի օրինակ։
Օպերատոր տեսակվերադարձնում է տող, որը ցույց է տալիս օպերանդի տեսակը:
Շարահյուսություն
Օպերանդը հետևում է օպերատորի տիպին.
տեսակ օպերանդ
Պարամետրեր
օպերանդարտահայտություն է, որը ներկայացնում է այն օբյեկտը կամ պարզունակը, որի տեսակը պետք է վերադարձվի:
Նկարագրություն
Հետևյալ աղյուսակը թվարկում է typeof-ի հնարավոր վերադարձի արժեքները: լրացուցիչ տեղեկությունտեսակների և պրիմիտիվների մասին՝ էջում։
Օրինակներ
// 37 տեսակի թվեր === «համար»; տեսակը 3.14 === «համար»; typeof(42) === «համար»; Մաթեմատիկայի տեսակը.LN2 === «համար»; Անսահմանության տեսակ === «թիվ»; NaN տեսակ === «թիվ»; // չնայած դա «Not-A-Number» տեսակի համար է (1) === «համար»; // երբեք չօգտագործել այս նշումը: // Strings typeof "" === "string"; տեսակ "bla" === "string"; տեսակ "1" === "string"; // նկատի ունեցեք, որ տողի ներսում թիվը դեռևս տիպի string typeof (տիպ 1) === "string"; // typeof-ը միշտ կվերադարձնի տող այս դեպքում typeof String("abc") === "string"; // երբեք չօգտագործել այս նշումը: // Booleans typeof true === «բուլյան»; typeof false === «բուլյան»; տեսակի բուլյան (ճշմարիտ) === «բուլյան»; // երբեք չօգտագործել այս նշումը: // Symbols typeof Symbol() === "symbol" typeof Symbol("foo") === "symbol" typeof Symbol.iterator === "symbol" // Undefined typeof undefined === "undefined"; typeof statementButUndefinedVariable === «չսահմանված»; typeof undeclaredVariable === «չսահմանված»; // Objects typeof(a: 1) === «օբյեկտ»; // օգտագործել Array.isArray կամ Object.prototype.toString.call // տարբերակել սովորական օբյեկտները և զանգվածները typeof === «օբյեկտ»; typeof new Ամսաթիվ () === «օբյեկտ»; // Ստորև բերված ցանկացած բան հանգեցնում է սխալների և խնդիրների: Չեն օգտագործում! նոր բուլյան (ճշմարիտ) տեսակ === «օբյեկտ»; նոր համարի տեսակ (1) === «օբյեկտ»; նոր տողի տեսակը ("abc") === "օբյեկտ"; // Functions typeof function() () === «function»; դասի տեսակը C() === «գործառույթ»; տեսակի Math.sin === «գործառույթ»;դատարկ
// Սա սահմանվել է JavaScript-ի ծննդյան օրվանից, null === «օբյեկտ»;JavaScript-ի առաջին ներդրման ժամանակ արժեքները ներկայացված էին պիտակի տեսակով և արժեքային զույգով: Օբյեկտների համար հատկորոշիչի տեսակը 0 էր: null-ը ներկայացված էր որպես զրոյական ցուցիչ (0x00 շատ հարթակներում): Հետևաբար, null-ի պիտակի տեսակը null էր, ուստի typeof-ի վերադարձի արժեքը կեղծ է: ()
ECMAScript-ում ուղղում է առաջարկվել (անջատման միջոցով), սակայն մերժվել է: Սա կհանգեցնի տեսակի null === «null» .
Օգտագործելով նոր օպերատորը
// «new»-ով ստեղծված բոլոր կոնստրուկտոր ֆունկցիաները կլինեն «object» տեսակի var str = new String(«String»); var num = նոր Համար (100); typeofstr; // Վերադարձնել «օբյեկտ» տեսակի num; // Վերադարձնում է «օբյեկտ» // Բայց կա բացառություն Function constructor var func = new Function(); ֆունկցիայի տեսակ; // Վերադարձեք «գործառույթը»Կանոնավոր արտահայտություններ
Կանոնավոր արտահայտությունները որոշ բրաուզերներում ոչ ստանդարտ հավելում էին:
Typeof /s/ === «գործառույթ»; // Chrome 1-12-ը չի համապատասխանում ECMAScript 5.1 տիպին /s/ === «օբյեկտ»; // Firefox 5+-ը համապատասխանում է ECMAScript 5.1-ին
Ժամանակավոր մեռած գոտիների հետ կապված սխալներ
Մինչև ECMAScript 2015-ը, օպերատորի տիպը երաշխավորված էր վերադարձնել տողը ցանկացած օպերանդի համար, որով այն կոչվեր: Սա փոխվեց՝ չբարձրացնող բլոկ-շրջանակով թողարկման և սահմանափակման հայտարարագրերի ավելացմամբ: Այժմ, եթե փոփոխականները հայտարարված են let-ով և const-ով, և typeof-ը նրանց վրա կանչվում է փոփոխականի հայտարարագրման բլոկում, բայց նախքան հայտարարումը, ապա ReferenceError է նետվում: Վարքագիծը տարբերվում է չհայտարարված փոփոխականներից, որոնց համար typeof-ը կվերադառնա «չսահմանված»: Բլոկի շրջանակով փոփոխականները գտնվում են «ժամանակավոր մեռած գոտում», որը տևում է բլոկի սկզբից մինչև փոփոխականների հայտարարագրման պահը։ Այս գոտում փոփոխականներ մուտք գործելու փորձը բացառություն է անում:
Typeof undeclaredVariable === "undefined"; newLetVariable-ի տեսակը; թող newLetVariable; // ReferenceError type of newConstVariable; const newConstVariable = "բարև"; // ReferenceError
Բացառություններ
Բոլոր ընթացիկ բրաուզերներում կա ոչ ստանդարտ document.all հոսթ օբյեկտ, որը տիպի Undefined է:
Typeof document.all === "undefined";
Թեև հստակեցումը թույլ է տալիս ոչ ստանդարտ էկզոտիկ օբյեկտների հատուկ տիպի անուններ, այդ անունները պետք է տարբերվեն նախապես սահմանվածներից: Իրավիճակը, երբ document.all-ը տիպի չսահմանված է, պետք է դիտարկել որպես կանոնների բացառիկ խախտում:
Տեխնիկական պայմաններ
Հստակեցում | Կարգավիճակ | Մեկնաբանություններ |
---|---|---|
ECMAScript-ի վերջին սևագիր (ECMA-262) |
Նախագիծ | |
ECMAScript 2015 (6-րդ հրատարակություն, ECMA-262) «Օպերատորի տեսակի» սահմանումը այս բնութագրում: |
Ստանդարտ | |
ECMAScript 5.1 (ECMA-262) «Օպերատորի տեսակի» սահմանումը այս բնութագրում: |
Ստանդարտ | |
ECMAScript 3-րդ հրատարակություն (ECMA-262) «Օպերատորի տեսակի» սահմանումը այս բնութագրում: |
Ստանդարտ | |
ECMAScript 1-ին հրատարակություն (ECMA-262) «Օպերատորի տեսակի» սահմանումը այս բնութագրում: |
Ստանդարտ | Նախնական սահմանում. Իրականացված JavaScript 1.1-ում |
Բրաուզերի համատեղելիություն
Թարմացրեք համատեղելիության տվյալները GitHub-ում
Համակարգիչներ | Բջջային | սերվեր | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Chrome | եզր | Firefox | Internet Explorer | Օպերա | սաֆարի | android վեբ դիտում | Chrome Android-ի համար | Firefox Android-ի համար | Օպերա Android-ի համար | Safari iOS-ում | Samsung ինտերնետ | Node.js | |
տեսակ | Chrome Ամբողջական աջակցություն 1 | եզր Ամբողջական աջակցություն 12 | Firefox Ամբողջական աջակցություն 1 | Ի.Է Ամբողջական աջակցություն 3 | Օպերա Ամբողջական աջակցությունԱյո՛ | սաֆարի Ամբողջական աջակցությունԱյո՛ | վեբ դիտում Android Ամբողջական աջակցություն 1 | Chrome Android Ամբողջական աջակցություն 18 | Firefox Android Ամբողջական աջակցություն 4 | OperaAndroid Ամբողջական աջակցությունԱյո՛ | Safari iOS Ամբողջական աջակցությունԱյո՛ | Samsung ինտերնետ Android Ամբողջական աջակցություն 1.0 | nodejs Ամբողջական աջակցությունԱյո՛ |
Լեգենդ
Ամբողջական աջակցությունԱմբողջական աջակցությունIE-ի հատուկ նշումներ
IE 6, 7 և 8-ում շատ հյուրընկալող օբյեկտներ օբյեկտներ են, այլ ոչ թե գործառույթներ: Օրինակ.