ფუნქცია
ფუნქციები არის ფუნდამენტალური ნაწილი JavaScript-ში. ფუნქციის იდეა მდგომარეობს, რომ შევქმნათ მრავალჯერადად გამოყენებადი კოდის ფრაგმენტი, რომელსაც გამოვიძახებთ სურვილისამებრ ნებისმიერ დროს. ფუნქციას შესაძლოა გადავცეთ სხვადასხვა ტიპის პარამეტრები, რის მიხედვითაც შესაძლოა შევინარჩოთ დინამიურობის პროცესი. დინამიურობის პროცესში იგულისხმება, გადაცემული პარამეტრიდან შესრულებული/დაბრუნებული მოქმედებები.
ფუნქციის ტიპები
ფუნქციები შესაძლოა დავყოთ ორ ტიპად:
- ფუნქცია, რომელიც მნიშვნელობას აბრუნებს (
return
ტიპის ფუნქციები). - ფუნქცია, რომელიც მნიშვნელობას არ აბრუნებს (
void
ტიპის ფუნქციები).
ყოველთვის არ არის სავალდებულო, რომ ფუნქციამ მნიშვნელობა დააბრუნოს, ამიტომაც გვაქვს ვოიდის ტიპის ფუნქციები. მათი დანიშნულება მდგომარეობს, რომ სხვადასხვა ტიპის მნიშვნელობები გაუშვას, მაგალითად: დაიწყოს თამაშის მთავარი ფუნქცია, განახლება გაუკეთოს ვიზუალს და ა.შ.
ფუნქცია, რომელსაც არ უწერია return
ავტომატურად იგულისხმება, რომ ეს ფუნქცია არის ვოიდის ტიპის, თუ შევეცდებით მისგან მნიშვნელობის წაკითხვას დაბრუნებული შედეგი ყოველთვის იქნება undefined
.
ფუნქციის აღწერა
ფუნქციის აღსაწერად გამოიყენება function
ქივორდი (keyword), რომლის შემდგომაც კეთდება შემდომგი ჩანაწერი:
- ფუნქციის სახელი (Camel case-ს სტილს)
- პარამეტრების სია, რომელიც ჩაწერილი იქნება
()
ფრჩხილებში, თითოეული პარამეტრის განსაცალკევებლად გამოიყენება,
(მძიმე). - კოდის ფრაგმენტი, რომელიც მოქცეული იქნება
{}
(ფიგურულ) ფრჩხილებში.
მაგალითსთვის აღვწეროთ მარტივი ფუნქცია, რომელიც ღებულობს რიცხვს და დავაბრუნოთ მისი კვადრატის მნიშვნელობა:
function square(number) {
return number * number;
}
ამ შემთხვევაში ფუნქცია square
ღებულობს ერთ პარამეტრს, სახელად number
-ს. როცა გამოვიძახებთ ფუნქცია square
აუცილებელი არის, რომ გადავცეთ number
მნიშვნელობა პარამეტრის სახით, არ გადაცემის შემთხვევაში მიენიჭება მას undefined
მნიშვნელობა, რაც არასწორ შედეგს დაგვიბრუნებს. გადმოცემულ მნიშვნელობას ვამბრავლებთ საკუთარ თავზე და მნიშვნელობას ვაბრუნებთ return
ქივორდით.
მაგალითისთვის გავტესტოთ ჩვენს მიერ დაწერილი ფუნქცია:
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) მნიშვნელობა. ნაგულისხმევი პარამეტრები უმჯობესია ეწეროს ჩვეულებრივ პარამეტრამდე. ნაგულისხმევი, რომ გახდეს პარამეტრი უბრალოდ უნდა მივანიჭოთ ფუნქციას მნიშვნელობა.
მაგალითი:
function logName(name = 'educata') {
console.log(`სასწავლებლის სახელია: ${name}`);
}
logName(); // 'სასწავლებლის სახელია: educata'
logName('EverREST'); // 'სასწავლებლის სახელია: EverREST'
კონკრეტულ შემთხვევაში აღვწერეთ ფუნქცია logName
, რომელსაც პარამეტრის არ გადაცემის შემთხვევაში მისი მნიშვნელობა გახდება educata
, რადგან ეს იყო name
პარამეტრის ნაგულისხმევი მნიშვნელობა, მაგრამ როცა მნიშვნელობა გადავეცით, მიიღო ის მნიშვნელობა, რაც პარამეტრის სახით მიიღო. ნაგულისხმევ პარამეტრს, ყოველთვის გადააწერს მნიშვნელობას გადაცემული მნიშვნელობა, რეალურად მეორე გამოძახების დროს ამიტომ მოგვცა განსხვავებული შედეგი.
მაგალითი:
function sum(a, b = 22) {
return a + b;
}
console.log(sum()); // NaN
console.log(sum(1)); // 23
console.log(sum(2, 2)); // 4
ფუნქციის ექსპრეშენები
ფუნქციის აღწერა არამხოლოდ იმ გზით არის შესაძლებელი, რაც მანამდე განვიხილეთ, არამედ შესაძლოა შეიქმნას ასევე ფუნქციის ექსფრეშენებით (გამოსახულებები). ფუნქცია შესაძლოა იყოს ანონიმური, როცა მას არ გააჩნია სახელი. მაგალითისთვის შესაძლოა ჩვენი ფუნქცია აგვეღწერა შემდგომ ნაირად:
const square = function (number) {
return number * number;
};
მსგავს ტიპად აღწერილი ფუნქცია არის ანონიმური და მისი გამოძახება შესაძლებელია ცვლადის სახელის გამოყენებით. თუმცა მსგავსად აღწერილი ფუნქცია არ გადის hoisting
-ს პროცესს ამიტომაც ხშირ შემთხვევაში უმჯობესია function
ქივორდის გამოყენება. მარტივად, რომ ავხსნათ ჰოისტინგი გულისხმობს ცვლადების/ფუნქციების წვდომას კონკრეტულ ადგილას, პირობითად შესაძლებელია ფუნქცია აღვწეროთ ქვემოთ და გამოვიძახოთ ზემოთ (ჰოისტინგზე დეტალური ინფორმაციისთვის იხილეთ hoisting
). მაგალითად:
console.log(square(5)); // ReferenceError: Cannot access 'square' before initialization
const square = function (number) {
return number * number;
};
const square = function (number) {
return number * number;
};
console.log(square(5)); // 25
console.log(square(16)); // 256
function square(number) {
return number * number;
}
console.log(square(32)); // 1024
პირველი მაგალითის შემთხვევაში წარმოიქმნა აქსსეს ერორი, რაც მოისაზრებს ცვლადის გამოყენებას მის ინიციალიზებამდე. მესამე მაგალითში იგივე პრობლემას არ ვაწყდებით, რადგან ფუნქცია გადის ჰოისტინგს, რაც შესაძლებლობას გვაძლევს, რომ გამოყენებადი იყოს მთლიან scope-ში (ან მთლიან აპლიკაციაში, თუ აღწერილი ფუნქცია, არის მთავარ JavaScript ფაილში).
პ.ს არ არის სავალდებულო კვადრატისთვის, ფუნქციის შემოღება, რადგან გვაქვს ბევრი მიდგომა, რომ კვადრატი მივიღოთ JavaScript-ში:
რეკურსია
რეკურსია არის მოვლენა , როდესაც რომელიმე ფუნქციაში ხდება იგივე ფუნქციის გამოძახება. ზოგიერთ ამოცანის ამოხსნის პროცესი შეიძლება წარმოვადგინოთ , ისეთი ტიპის პრინციპით სადაც ფუნქცია იძახებს საკუთარ თავს და შევასრულოთ რეკურსიულად.
// გრძელი 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
შიგნით და არ შეიძლება მათი გამოყენება, როგორც გენერატორი ფუნქცია.
მისი სინტაქსი სახელს ამართლებს. მისი სინტაქსი:
() => ფუნქციის შედეგი
param => ფუნქციის შედეგი
(param) => ფუნქციის შედეგი
(param1, paramN) => ფუნქციის შედეგი
() => {
ფუნქციის კოდი
}
param => {
ფუნქციის კოდი
}
(param1, paramN) => {
ფუნქციის კოდი
}
სინტაქსის მაგალითი:
const printHere = () => {
console.log('Here');
};
printHere(); // დაილოგება "Here"
// შემდგომ სტატიებში იქნება უფრო მეტი მაგალითი განხილული
ასინქრონული ფუნქციები
ასინქრონული ტიპის ფუნქციები საშუალების გვაძლევს promise
-ებს მოვუსმინოთ await
ქივორდის საშუალებით, შედეგად კი ვღებულობთ უფრო სუფთა კოდს (თავს ვარიდებთ პრომისების გრძელ კოდს).
ასინქრონული პროგრამირების იდეა განხილული იქნება promise & async
თავში.