ფუნქცია

ფუნქციები არის ფუნდამენტალური ნაწილი JavaScript-ში. ფუნქციის იდეა მდგომარეობს, რომ შევქმნათ მრავალჯერადად გამოყენებადი კოდის ფრაგმენტი, რომელსაც გამოვიძახებთ სურვილისამებრ ნებისმიერ დროს. ფუნქციას შესაძლოა გადავცეთ სხვადასხვა ტიპის პარამეტრები, რის მიხედვითაც შესაძლოა შევინარჩოთ დინამიურობის პროცესი. დინამიურობის პროცესში იგულისხმება, გადაცემული პარამეტრიდან შესრულებული/დაბრუნებული მოქმედებები.

ფუნქციის ტიპები

ფუნქციები შესაძლოა დავყოთ ორ ტიპად:

  • ფუნქცია, რომელიც მნიშვნელობას აბრუნებს (return ტიპის ფუნქციები).
  • ფუნქცია, რომელიც მნიშვნელობას არ აბრუნებს (void ტიპის ფუნქციები).

ყოველთვის არ არის სავალდებულო, რომ ფუნქციამ მნიშვნელობა დააბრუნოს, ამიტომაც გვაქვს ვოიდის ტიპის ფუნქციები. მათი დანიშნულება მდგომარეობს, რომ სხვადასხვა ტიპის მნიშვნელობები გაუშვას, მაგალითად: დაიწყოს თამაშის მთავარი ფუნქცია, განახლება გაუკეთოს ვიზუალს და ა.შ.

ფუნქცია, რომელსაც არ უწერია return ავტომატურად იგულისხმება, რომ ეს ფუნქცია არის ვოიდის ტიპის, თუ შევეცდებით მისგან მნიშვნელობის წაკითხვას დაბრუნებული შედეგი ყოველთვის იქნება undefined.

ფუნქციის აღწერა

ფუნქციის აღსაწერად გამოიყენება function ქივორდი (keyword), რომლის შემდგომაც კეთდება შემდომგი ჩანაწერი:

  • ფუნქციის სახელი (Camel case-ს სტილს)
  • პარამეტრების სია, რომელიც ჩაწერილი იქნება () ფრჩხილებში, თითოეული პარამეტრის განსაცალკევებლად გამოიყენება , (მძიმე).
  • კოდის ფრაგმენტი, რომელიც მოქცეული იქნება {} (ფიგურულ) ფრჩხილებში.

მაგალითსთვის აღვწეროთ მარტივი ფუნქცია, რომელიც ღებულობს რიცხვს და დავაბრუნოთ მისი კვადრატის მნიშვნელობა:

JS
function square(number) {
  return number * number;
}

ამ შემთხვევაში ფუნქცია square ღებულობს ერთ პარამეტრს, სახელად number-ს. როცა გამოვიძახებთ ფუნქცია square აუცილებელი არის, რომ გადავცეთ number მნიშვნელობა პარამეტრის სახით, არ გადაცემის შემთხვევაში მიენიჭება მას undefined მნიშვნელობა, რაც არასწორ შედეგს დაგვიბრუნებს. გადმოცემულ მნიშვნელობას ვამბრავლებთ საკუთარ თავზე და მნიშვნელობას ვაბრუნებთ return ქივორდით.

მაგალითისთვის გავტესტოთ ჩვენს მიერ დაწერილი ფუნქცია:

JS
function square(number) {
  return number * number;
}

console.log(square(2)); // 4
console.log(square(4)); // 16
console.log(square(8)); // 64
console.log(square()); // NaN

ფუნქციის პარამეტრები

ფუნქციას შესაძლოა იმდენი პარამეტრი გადავცეთ რამდენიც გვსურს. თითოეული პარამეტრი ერთმანეთისაგან უნდა იყოს გამოყოფილი , (მძიმით). თითოეული პარამეტრი შესაძლოა მივანიჭოთ ნაგულისხმევი (default) მნიშვნელობა. ნაგულისხმევი პარამეტრები უმჯობესია ეწეროს ჩვეულებრივ პარამეტრამდე. ნაგულისხმევი, რომ გახდეს პარამეტრი უბრალოდ უნდა მივანიჭოთ ფუნქციას მნიშვნელობა.

მაგალითი:

JS
function logName(name = 'educata') {
  console.log(`სასწავლებლის სახელია: ${name}`);
}

logName(); // 'სასწავლებლის სახელია: educata'
logName('EverREST'); // 'სასწავლებლის სახელია: EverREST'

კონკრეტულ შემთხვევაში აღვწერეთ ფუნქცია logName, რომელსაც პარამეტრის არ გადაცემის შემთხვევაში მისი მნიშვნელობა გახდება educata, რადგან ეს იყო name პარამეტრის ნაგულისხმევი მნიშვნელობა, მაგრამ როცა მნიშვნელობა გადავეცით, მიიღო ის მნიშვნელობა, რაც პარამეტრის სახით მიიღო. ნაგულისხმევ პარამეტრს, ყოველთვის გადააწერს მნიშვნელობას გადაცემული მნიშვნელობა, რეალურად მეორე გამოძახების დროს ამიტომ მოგვცა განსხვავებული შედეგი.

მაგალითი:

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

console.log(sum()); // NaN
console.log(sum(1)); // 23
console.log(sum(2, 2)); // 4

ფუნქციის ექსპრეშენები

ფუნქციის აღწერა არამხოლოდ იმ გზით არის შესაძლებელი, რაც მანამდე განვიხილეთ, არამედ შესაძლოა შეიქმნას ასევე ფუნქციის ექსფრეშენებით (გამოსახულებები). ფუნქცია შესაძლოა იყოს ანონიმური, როცა მას არ გააჩნია სახელი. მაგალითისთვის შესაძლოა ჩვენი ფუნქცია აგვეღწერა შემდგომ ნაირად:

JS
const square = function (number) {
  return number * number;
};

მსგავს ტიპად აღწერილი ფუნქცია არის ანონიმური და მისი გამოძახება შესაძლებელია ცვლადის სახელის გამოყენებით. თუმცა მსგავსად აღწერილი ფუნქცია არ გადის hoisting-ს პროცესს ამიტომაც ხშირ შემთხვევაში უმჯობესია function ქივორდის გამოყენება. მარტივად, რომ ავხსნათ ჰოისტინგი გულისხმობს ცვლადების/ფუნქციების წვდომას კონკრეტულ ადგილას, პირობითად შესაძლებელია ფუნქცია აღვწეროთ ქვემოთ და გამოვიძახოთ ზემოთ (ჰოისტინგზე დეტალური ინფორმაციისთვის იხილეთ hoisting). მაგალითად:

JS
console.log(square(5)); // ReferenceError: Cannot access 'square' before initialization

const square = function (number) {
  return number * number;
};
JS
const square = function (number) {
  return number * number;
};
console.log(square(5)); // 25
JS
console.log(square(16)); // 256

function square(number) {
  return number * number;
}

console.log(square(32)); // 1024

პირველი მაგალითის შემთხვევაში წარმოიქმნა აქსსეს ერორი, რაც მოისაზრებს ცვლადის გამოყენებას მის ინიციალიზებამდე. მესამე მაგალითში იგივე პრობლემას არ ვაწყდებით, რადგან ფუნქცია გადის ჰოისტინგს, რაც შესაძლებლობას გვაძლევს, რომ გამოყენებადი იყოს მთლიან scope-ში (ან მთლიან აპლიკაციაში, თუ აღწერილი ფუნქცია, არის მთავარ JavaScript ფაილში).

პ.ს არ არის სავალდებულო კვადრატისთვის, ფუნქციის შემოღება, რადგან გვაქვს ბევრი მიდგომა, რომ კვადრატი მივიღოთ JavaScript-ში:

  • ** ხარისხის ოპერატორის სახით
  • Math.pow მეთოდის გამოყენებით

რეკურსია

რეკურსია არის მოვლენა , როდესაც რომელიმე ფუნქციაში ხდება იგივე ფუნქციის გამოძახება. ზოგიერთ ამოცანის ამოხსნის პროცესი შეიძლება წარმოვადგინოთ , ისეთი ტიპის პრინციპით სადაც ფუნქცია იძახებს საკუთარ თავს და შევასრულოთ რეკურსიულად.

JS
// გრძელი if/else ჩაწერით
function pow(x, n) {
  if (n === 1) {
    return x;
  } else {
    return x * pow(x, n - 1);
  }
}
// ტერნარული ოპერატორის ჩანაწერით
function powTernary(x, n) {
  return n === 1 ? x : x * powTernary(x, n - 1);
}
// შედეგი ორივე ფუნქციისთვის ერთი და იგივე არის მაგრამ ტერნარული ოპერატორით ჩანაწერი უფრო მოკლე არის და არ მოითხოვს ზედმეტი if/else ჩანაწერის ბლოკებს
console.log(pow(2, 10)); // 1024
console.log(powTernary(2, 10)); // 1024

განვიხილოთ მაგალითი თითოეული რეკურსიული იტერაციისთვის.

  • pow(2, 10) = 2 * pow(2, 9)
  • pow(2, 9) = 2 * pow(2, 8)
  • pow(2, 8) = 2 * pow(2, 7)
  • pow(2, 7) = 2 * pow(2, 6)
  • pow(2, 6) = 2 * pow(2, 5)
  • pow(2, 5) = 2 * pow(2, 4)
  • pow(2, 4) = 2 * pow(2, 3)
  • pow(2, 3) = 2 * pow(2, 2)
  • pow(2, 2) = 2 * pow(2, 1)
  • pow(2, 1) = 2
  • საბოლოო ჯამში მიიღება: 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2

pow ფუნქცია რეკურსიულად იძახებს თავის თავს მანამ სანამ n არ გაუტოლდება 1.

განსხვავებული მაგალითი რეკურსიულად ფაილების წაკითხვა-ზე:

უშუალოდ iswavle.com-ს აწყობისას, კონტენტის დასარენდერებლად რეკურსია არის გამოყენებული, იხილეთ კოდი.

ჰანოის კოშკი რეკურსიულად

ალბათ ერთხელ მაინც ყველას გვითამაშია ჰანოის კოშკი. მისი იდეა მარტივია ერთი საყრდენი ჯოხიდან უნდა გადავიტანოთ რგოლები მეორე საყრდენ ჯოხზე ისე, რომ რამოდენიმე წესი არ დავარღვიოთ. წესები შემდგომია:

  • ერთ გადატანაზე გადაგვაქვს მხოლოდ ერთი რგოლი.
  • დიდ რგოლს, პატარა რგოლზე ვერ დავდებთ.
  • საყრდენი ჯოხიდან მხოლოდ პირველი რგოლის აღება შეგვიძლია (რაც ზემოთ არის).

ჰანოის კოშკის მაგალითი

Arrow ფუნქცია

arrow ფუნქცია არის ალტერნატივა ჩვეულებრივი ფუნქციის, მცირედი მოდიფიცირებებით. მისი სინტაქსი შემოკლდა და შეიცვალა მცირედადა გამოყენებების სტანდარტები:

  • arrow ფუნქციას არ გააჩნია თავიანთი: this (განხილული არის შემდგომ თავშიც), arguments, super და არ შეიძლება მათი გამოყენება, როგორც მეთოდების სახით.
  • arrow ფუნქციას ვერ გამოვიყენებთ, როგორც constructor. მათი გამოძახება new თანხლებით გამოიტანს TypeError-ს.
  • arrow ფუნქცია არ შეიძლება იყოს გამოყენებული yield შიგნით და არ შეიძლება მათი გამოყენება, როგორც გენერატორი ფუნქცია.

მისი სინტაქსი სახელს ამართლებს. მისი სინტაქსი:

JS
() => ფუნქციის შედეგი

param => ფუნქციის შედეგი

(param) => ფუნქციის შედეგი

(param1, paramN) => ფუნქციის შედეგი

() => {
  ფუნქციის კოდი
}

param => {
  ფუნქციის კოდი
}

(param1, paramN) => {
  ფუნქციის კოდი
}

სინტაქსის მაგალითი:

JS
const printHere = () => {
  console.log('Here');
};

printHere(); // დაილოგება "Here"
// შემდგომ სტატიებში იქნება უფრო მეტი მაგალითი განხილული

ასინქრონული ფუნქციები

ასინქრონული ტიპის ფუნქციები საშუალების გვაძლევს promise-ებს მოვუსმინოთ await ქივორდის საშუალებით, შედეგად კი ვღებულობთ უფრო სუფთა კოდს (თავს ვარიდებთ პრომისების გრძელ კოდს).

ასინქრონული პროგრამირების იდეა განხილული იქნება promise & async თავში.