Skip to content

Latest commit

 

History

History
65 lines (47 loc) · 9.78 KB

Unlocking the Power of Pseudo-Array Arguments in Functions.hy.md

File metadata and controls

65 lines (47 loc) · 9.78 KB

Այս գրառման մեջ մենք կանդրադառնանք ֆունկցիաների ներսում հասանելի arguments փսևդոզանգվածին: Որտե՞ղ է կարելի այն կիրառել, և ինչու՞ ժամանակակից կոդի մեջ այն ավելի ու ավելի հազվադեպ է օգտագործվում՝ փոխարինվելով rest parameter (...rest) սինթաքսով:

JavaScript-ում ֆունկցիաները կարող են կանչվել ցանկացած քանակությամբ արգումենտներով՝ անկախ նրանից, թե ֆունկցիայի հայտարարման ժամանակ մենք քանի պարամետր ենք սահմանել։ Օրինակ՝ ստեղծենք թվերի գումարման պարզագույն ֆունկցիա։

function sum(a, b) {
  return a + b;
}

console.log(sum(2)); // NaN
console.log(sum(5, 3)); // 8
console.log(sum(4, 7, 9)); // 11

Ֆունկցիան ունի երկու պարամետր` a և b, կանչի ժամանակ այն վերադարձնում է դրանց գումարը։ Եթե մենք ֆունկցիան կանչենք մեկ արգումենտով՝ այդ արգումենտը կվերագրվի a-ին, իսկ b-ին անուղղակիորեն կվերագրվի undefined: հետևաբար ֆունկցիան կվերադարձնի NaN, քանի-որ փորձելով undefined արժեքը անուղղակիորեն վերածել թվի, կստանա NaN, իսկ ինչպես հիշում ենք, NaN-ի հետ ցանկացած մաթեմատիկական գործողության արդյունքը միշտ կլինի NaN:

Երկրորդ օրինակը հասկանալի է, պետք է ստանար երկու արգումենտ, այդքան էլ ստացել է և վերադարձրել դրանց գումարը։ Երրորդ օրինակում մենք տալիս ենք երեք արգումենտ, թեև ֆունկցիան սահմանել ենք երկու պարամետրով, հետևաբար մեր տված երրորդ արգումենտն ուղղակի անտեսվում է։ Մենք կարող ենք ֆունկցիան կանչել թեկուզ 10 արգումենտներով, ոչ մի սխալ չի լինի, ուղղակի բացի առաջինից և երկրորդից՝ մնացած բոլոր արգումենտներն անտեսվելու են։

Սակայն ֆունկցիայի մեջ հնարավոր է հասանելիություն ստանալ նրա կանչի ժամանակ հաղորդված բոլոր արգումենտներին։ Դրա համար JavaScript-ում գոյություն ունի հատուկ ներդրված օբյեկտ՝ arguments, որը նման է զանգվածի, բայց զանգված չէ, և իրենից ներկայացնում է բոլոր արգումենտների հավաքածուն։ Փաստացի arguments փսևդոզանգվածը (փսևդո բառարմատը հունարենից թարգմանած նշանակում է կեղծ, այսինքն բառացիորեն՝ կեղծ զանգված, այդպիսի օբյեկտներին հաճախ անվանում են նաև զանգվածանման օբյեկտներ) դա լոկալ փոփոխական է, որը հասանելի է ֆունկցիայի մարմնի մեջ։ Ի դեպ այն գոյություն ունի բոլոր տեսակի ֆունկցիաների մեջ՝ անկախ ստեղծման եղանակից, բացի arrow function-ներից (լյամբդա ֆունկցիաներ):

Ինչու՞ է կոչվում փսևդոզանգված։ Որովհետև այն զանգված չէ, այլ սովորական օբյեկտ, ուղղակի նրա հատկությունների բանալիներն ամբողջ թվերի հեշտությամբ վերափոխվող, սակայն String տիպին պատկանող արժեքներ են՝ սկսած "0"-ից, ապա "1", "2", ․․․ "n" (անգլերեն կոչվում են integer key-եր): Փսևդոզանգվածները նաև ունեն length հատկություն, որը ցույց է տալիս այդ զանգվածանման օբյեկտների հատկությունների քանակը։ Սակայն նրա վրա մենք չենք կարող օգտագործել զանգվածի մեթոդները՝ օրինակ push, map կամ ասենք reduce: Ստեղծենք որևէ ֆունկցիա, որը կարտածի այդ փսևդոզանգվածի առանձին էլեմենտները, որպեսզի ամեն ինչ ավելի պարզ լինի։

function foo() {
  console.log(arguments.length);
  console.log(arguments[0]);
  console.log(arguments[1]);
  console.log(arguments[2]);
}

foo(3, 5);

Կանչելով ֆունկցիան երկու արգումենտներով, մենք կտեսնենք, որ կոնսոլում համապատասխանաբար տպվում է argumnets.length-ը՝ 2, arguments[0]-ն՝ 3, և arguments[1]-ը՝ 5։ Իսկ arguments[2]undefined է, քանի-որ մենք երրորդ արգումենտ չենք հաղորդել, և նրան անուղղակիորեն վերագրվում է անորոշ արժեք՝ undefined։

JavaScript-ում կան մի շարք ներդրված մեթոդներ՝ օրինակ Math․max-ը, որը կարող է ստանալ ցանկացած քանակությամբ արգումենտներ։ Մենք նույնպես կարող ենք ստեղծել ֆունկցիաներ, որոնք կստանան կամայական քանակությամբ արգումենտներ և նրանց հետ ինչ-որ գործողություն կկատարեն։ Օրինակ ստեղծենք պարզագույն ֆունկցիա, որը կստանա կամայական քանակի արգումենտներ և կվերադարձնի նրանց գումարը։ Նախկինում սա հնարավոր էր անել միայն arguments փսևդոզանգվածի օգնությամբ, այժմ կա ավելի ժամանակակից եղանակ, որին նույնպես կանդրադառնամ։ Ֆունկցիան ստեղծենք այդ ժամանակների «ոգուն» համապատասխան՝ փոփոխականների հայտարարման համար օգտագործելով var բանալի բառը, իսկ փսևդոզանգվածի իտերացիայի համար՝ սովորական for ցիկլը, թեև ավելի հարմար կլիներ for of-ը։

function sumOfArgs() {
  var sum = 0;
  for (var i = 0; i < arguments.length; i++) {
    sum += arguments[i];
  }
  return sum;
}

console.log(sumOfArgs(2, 3)); // Output: 5
console.log(sumOfArgs(2, 3, 5)); // Output: 10

Նաև նախկինում որպեսզի arguments փսևդոզանգվածի հետ հնարավոր լիներ աշխատել զանգվածի ներդրված մեթոդներով՝ օրինակ map-ով, ստիպված էին օգտագործել ֆունկցիաների call մեթոդը, կամ էլ այլընտրանքը՝ ցիկլի օգնությամբ պտտվելով arguments փսևդոզանգվածի վրա՝ յուրաքանչյուր էլեմենտի հետ կատարել նախատեսված փոփոխությունը և ավելացնել նախապես ստեղծված դատարկ զանգվածի մեջ։

Ժամանակակից կոդի մեջ գնալով ավելի հազվադեպ է օգտագործվում arguments ներդրված փսևդոզանգվածը, քանի-որ գոյություն ունի շատ անգամ ավելի հարմար rest parameter-ի սինթաքսը։ Այն ստեղծվում է ․․․ օպերատորի օգնությամբ (ինչպես հայերենի կախման կետերի կետադրական նշանը), և ֆունկցիայի ստեղծման ժամանակ կարող է իր մեջ «հավաքել» կամայական քանակի արգումենտներն ու ֆունկցիայի մարմնում տալ դրանց հասանելիություն։ Ընդ որում փոփոխականը, որն իր մեջ պարունակում է այդ արգումենտները՝ զանգված է, հետևաբար ի տարբերություն arguments փսևդոզանգվածի՝ առանց լրացուցիչ ջանքերի կարելի է զանգվածի տասնյակ մեթոդներ կիրառելով կատարել բոլոր այն մանիպուլյացիաները, որոնք մեզ անհրաժեշտ են։ Օրինակ նույն այն պարզագույն ֆունկցիան, որը ստանում էր կամայական քանակի թվային արժեքով արգումենտներ և վերադարձնում դրանց գումարը, rest parameter սինթաքսի օգնությամբ կարող է ունենալ հետևյալ տեսքը՝

function sumOfArgs(...rest) {
  return rest.reduce((acc, elem) => acc + elem, 0);
}

console.log(sumOfArgs(2, 3)); // Output: 5
console.log(sumOfArgs(5, 10, 15)); // Output: 30
console.log(sumOfArgs(7, 8, 5, 6, 9)); // Output: 35

rest-ն ուղղակի պարամետրի անունն է, այդպես ընդունված է անվանել, բայց բնականաբար ոչ մի պարտադրանք չկա՝ կարելի է անվանել args կամ ցանկացած այլ անունով, եթե իհարկե ռեզերվ արած բառ չէ։ Կա միայն մի պարտադրանք՝ rest պարամետրը միշտ պետք է լինի վերջում, այն իր մեջ հավաքում է մնացյալ արգումենտները, և անիմաստ է նրանից հետո որևէ այլ պարամետր սահմանել։ Սակայն նրանից առաջ այլ պարամետրեր կարող են լինել։