JavaScript үндэс / Функциональ программчлал

Функциональ программчлал

Функциональ программчлал (Functional Programming) нь кодыг бичих өөр нэг хандлага юм. Үүний гол санаа нь: функцүүдийг жижиг, цэвэр, урьдчилан таамаглах боломжтой байлгах. Та map, filter, reduce методуудыг өмнө нь үзсэн — тэдгээр нь функциональ хандлагын жишээ юм. Энэ хичээлд тэдгээрийн ард байдаг ойлголтуудыг гүнзгийрүүлнэ.

Цэвэр функц (Pure function)

Цэвэр функц гэдэг нь: ижил оролт → заавал ижил гаралт, гаднах ямар нэг зүйлийг өөрчилдөггүй функц. Энэ нь туршихад хялбар, алдаа олоход хялбар болгодог.

javascript
// Цэвэр функц — гаднах зүйлд хамаарахгүй
function нэмэх(а, б) {
  return а + б; // заавал ижил үр дүн
}

// Цэвэр БУС функц — гаднах хувьсагчаас хамаарна
let нэмэлт = 10;
function нэмэлт_нэмэх(тоо) {
  return тоо + нэмэлт; // нэмэлт өөрчлөгдвөл үр дүн өөр болно
}

console.log(нэмэх(3, 4)); // заавал 7

Хувьсашгүй байдал (Immutability)

Функциональ хандлагад одоо байгаа өгөгдлийг шууд өөрчилдөггүй — харин шинэ хуулбар үүсгэнэ. Энэ нь алдааны эх үүсвэрийг багасгадаг.

javascript
// Муу — массивыг шууд өөрчилж байна
const тоонууд = [1, 2, 3];
тоонууд.push(4); // эх массивыг өөрчилсөн

// Сайн — шинэ массив үүсгэж байна
const тоонууд2 = [1, 2, 3];
const шинэ = [...тоонууд2, 4]; // тоонууд2 хэвээр үлдэнэ
console.log(тоонууд2); // [1, 2, 3]
console.log(шинэ); // [1, 2, 3, 4]

// Объекттой мөн адил
const хэрэглэгч = { нэр: "Болд", нас: 24 };
const шинэ_хэрэглэгч = { ...хэрэглэгч, нас: 25 }; // шинэ объект
console.log(хэрэглэгч.нас); // 24 — өөрчлөгдсөнгүй
console.log(шинэ_хэрэглэгч.нас); // 25

Дээд зэргийн функц (Higher-order function)

Функцийг аргумент болгон авах эсвэл функцийг буцаах функцийг higher-order function гэнэ. map, filter, reduce бүгд үүнд хамаарна.

javascript
// Функц буцаадаг функц — closure ашиглан
function үржүүлэгч_үүсгэх(тоо) {
  return function (утга) {
    return утга * тоо;
  };
}

const хоёр_дахин = үржүүлэгч_үүсгэх(2);
const гурав_дахин = үржүүлэгч_үүсгэх(3);

console.log(хоёр_дахин(5)); // 10
console.log(гурав_дахин(5)); // 15

// Функцийг аргумент болгон дамжуулах
function хэрэглэх(утга, функц) {
  return функц(утга);
}

console.log(хэрэглэх(10, хоёр_дахин)); // 20
console.log(хэрэглэх(10, (x) => x + 1)); // 11

Function composition — функцүүдийг гинжлэх

Жижиг функцүүдийг нэгтгэж нарийн төвөгтэй үйлдэл хийх нь функциональ программчлалын гол хүч:

javascript
const оноо = [45, 80, 92, 30, 67, 88, 55];

const дүн = оноо
  .filter((о) => о >= 60) // 60-аас дээш: [80, 92, 67, 88]
  .map((о) => о * 1.1) // 10% нэмэх:   [88, 101.2, 73.7, 96.8]
  .map((о) => Math.round(о)) // бүхэлд:      [88, 101, 74, 97]
  .reduce((нийт, о) => нийт + о, 0); // нийлбэр: 360

console.log(дүн); // 360
javascript
// compose — функцүүдийг баруунаас зүүнд гүйцэтгэх
const compose =
  (...функцүүд) =>
  (утга) =>
    функцүүд.reduceRight((acc, fn) => fn(acc), утга);

const боловсруулах = compose(
  (x) => x * 2, // 3. хоёр дахин нэмэх
  (x) => x + 10, // 2. арав нэмэх
  (x) => x - 3, // 1. гурав хасах
);

console.log(боловсруулах(5)); // ((5-3)+10)*2 = 24

Функциональ хандлага нь React, Redux зэрэг орчин үеийн сангуудын үндэс суурь юм. Эдгээр ойлголтыг эзэмшсэнээр бусдын кодыг уншиж ойлгох, өөрийн кодыг найдвартай болгох чадвар мэдэгдэхүйц өснө.

Дараагийн хичээлд:

Design Pattern үндэс — томоохон кодод байнга тохиолддог асуудлуудыг шийдэх батлагдсан загваруудыг үзнэ.