Faktiski ir vairāki programmēšanas stili, arī zināmi kā paradigmas. Viens izplatīts stils ir saucams par funkcionālo programmēšanu vai īsi FP.
Funkcionālajā programmēšanā mēs daudz lietojam funkcijas un mainīgos.
function getTotal(a,b) {
return a + b
}
var num1 = 2;
var num2 = 3;
var total = getTotal(num1, num2);
function getDistance(mph, h) {
return mph * h
}
var mph = 60;
var h = 2;
var distance = getDistance(mph, h);
objektorientētā programmēšana (OOP) ir vēl viens plaši izmantots programmēšanas stils. Objektorientētajā programmēšanā dati un funkcionalitāte tiek grupēti kā īpašības un metodes objektos.
Piemēram, ja mums ir virtuālais mājdzīvnieks (virtualPet) objekts, mēs varam dot tam miegainības īpašību un guļammetodes (nap()) metodi:
virtualPet = {
sleepy: true,
nap: function() {
this.sleepy = false;
}
}
Objektorientētā programmēšana ļauj mums radīt kompleksas un modulāras sistēmas, jo mēs varam radīt dažādus objektus, kuriem ir atšķirīga īpašību un metožu kopa, un pēc tam šos objektus savstarpēji savienot un izmantot kopējā sistēmā. Tāpat OOP ļauj mums radīt klases, kas ir objektu sabiedriskās sastāvdaļas, un tad no tām radīt jaunus objektus, kas ir šo klašu “instances”. Objektorientētā programmēšana ir plaši izmantota programmēšanas pieeja dažādās jomās, piemēram, mobilo aplikāciju un spēļu izstrādē.
Objektorientētajā programmēšanā metodes atjauno objektā saglabātās īpašības, nevis rada jaunas atgriezeniskās vērtības.
Piemēram, ja pārbaudām virtuālā mājdzīvnieka (virtualPet) objekta miegainības īpašību, varam apstiprināt, ka tā ir uzstādīta uz “true”.
Taču, kad esam izpildījuši virtuālā mājdzīvnieka objektā guļammetodes (nap()) metodi, vai miegainības īpašības vērtība mainīsies? Jā, pēc metodes izpildes miegainības īpašības vērtība mainīsies uz “false”, jo metode mainīs šo īpašības vērtību.
virtualPet.sleepy; // true
virtualPet.nap();
virtualPet.sleepy; // false
virtualPet = {
birthday: "2022-26-12",
age: function() {
let today = new Date();
let birthday = new Date(this.birthday);
let age = today.getFullYear() - birthday.getFullYear();
let m = today.getMonth() - birthday.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthday.getDate())) {
age--;
}
return age;
}
}
virtualPet.age(); // izvada virtuālā dzīvnieka vecumu gados
Objektorientētā programmēšana palīdz mums modelēt reālas dzīves objektus. Tā strādā labāk, ja objektā esošo īpašību un datu grupējums ir loģisks – tas nozīmē, ka īpašības un metodes “sader kopā”.
Ņemiet vērā, ka mērķis šeit nav apspriest objektorientēto programmēšanu sīkāk; tā vietā es vēlos parādīt jums vienkāršāko objektorientētās programmēšanas aprakstu, lai parādītu vienu no svarīgākajām atšķirībām starp funkcionālo programmēšanu un objektorientēto programmēšanu.
Lai kopsavilktu šo punktu, varam teikt, ka funkcionālās programmēšanas paradigma strādā,lai saglabājot datus un funkcionalitāti atsevišķi. Tās pretstats, objektorientētā programmēšana, strādā,lai saglabājot datus un funkcionalitāti grupētu nozīmīgos objektos.”
Funkcionālajā programmēšanā ir daudz vairāk koncepciju un ideju.
Šeit ir dažas no svarīgākajām:
- Pirmās klases funkcijas
- Augstākās kārtas funkcija
- Tīras funkcijas un blakus efekti
Funkcionālajā programmēšanā ir daudz citu koncepciju un principu, bet šobrīd paliekam pie šīm trīs.
– Pirmās klases funkcijas Bieži tiek teikts, ka funkcijas JavaScript ir “pirmās klases pilsoņi”. Kas tas nozīmē?
Tas nozīmē, ka JavaScript funkcija ir vēl viena vērtība, kuru varam:
- nodot citām funkcijām
- saglabāt mainīgajā
- atgriezt no citām funkcijām
Citas vārdiem sakot, JavaScript funkcija ir tikai vērtība – no šī skatupunkta, gandrīz nekāda atšķirība no vērtībām, piemēram, teksta vai skaitļa.
Piemēram, JavaScript ir pilnīgi normāli nodot funkcijas izsaukumu citai funkcijai.
Lai izskaidrotu, kā tas strādā, aplūkojiet sekojošo programmu.
function addTwoNums(a, b) {
console.log(a + b)
}
function randomNum() {
returnMath.floor((Math.random() * 10) + 1);
}
function specificNum() { return42 };
var useRandom = true;
var getNumber;
if(useRandom) {
getNumber = randomNum
} else {
getNumber = specificNum
}
addTwoNums(getNumber(), getNumber())
Es uzsāku programmu ar addTwoNums() funkciju, kuras definīciju es jau izmantoju iepriekš dažādās variācijās. Iemesls, kāpēc šī funkcija ir atkārtojošs piemērs, ir tādēļ, ka tā ir tik vienkārša, ka tā palīdz izskaidrot citādi grūtāk saprotamus koncepcijas.
Tālāk es kodēju funkciju ar nosaukumu randomNum(), kas atgriež nejaušu skaitli no 0 līdz 10.
Tad es kodēju vēl vienu funkciju ar nosaukumu specificNum(), kas atgriež noteiktu skaitli, skaitli 42.
Tālāk es saglabāju mainīgo ar nosaukumu useRandom un iestatīju tā vērtību uz “true” boolean vērtību. Es deklarēju vēl vienu mainīgo, ar nosaukumu getNumber.
Šeit lietas kļūst interesantas…
Turpmākajās vairākās rindās ir if else izteiksme. If nosacījums tiek izpildīts, ja useRandom vērtība ir iestatīta uz “true”. Ja tā ir, tad visu randomNum() funkcijas deklarāciju saglabājam getNumber mainīgajā. Citādi es saglabāju visu specificNum() funkcijas deklarāciju getNumber mainīgajā.
Citiem vārdiem sakot, pamatojoties uz useRandom vērtību, kas iestatīta uz “true” vai “false”, getNumber mainīgais tiks piešķirts vai nu randomNum() funkcijas deklarācijā, vai arī specificNum() funkcijas deklarācijā.
Ar visu šo kodu iestatītu, es varu pēc tam izsaukt addTwoNums() funkciju, nododot tai getNumber() mainīgā izsaukumu kā pirmo un otro argumentu.
Tas darbojas, jo funkcijas JavaScript tiešām ir pirmās klases pilsoņi, kuras var piešķirt mainīgajiem un nodot apkārt tāpat, kā es nodotu apkārt tekstu, skaitli, objektu utt.
Piezīme: lielākā daļa koda randomNum() funkcijas deklarācijā ir nākuši no iepriekšējās nodarbības, konkrēti no nodarbības, kurā tika apspriesti Math objekts JavaScript.
Tādējādi es nonāku pie otrās funkcionālās programmēšanas pamatkoncepcijas, kas ir augstākās kārtas funkciju koncepcija.
Augstākās kārtas funkcijas
Augstākās kārtas funkcija ir funkcija, kurai ir viens vai abi no šādiem raksturlielumiem:
- Tā pieņem citas funkcijas kā argumentus
- Tā atgriež funkcijas, kad tiek izsaukta
Nav nekāda “īpaša veida”, kā definēt augstākās kārtas funkcijas JavaScript. Tā ir vienkārši valodas iezīme. Valoda pati ļauj man nodot funkciju citai funkcijai vai atgriezt funkciju no citas funkcijas.
Turpinot no iepriekšējās sadaļas, aplūkojiet sekojošo kodu, kurā es atkārtoti definēju addTwoNums() funkciju, lai tā kļūtu par augstākās kārtas funkciju:
function addTwoNums(getNumber1, getNumber2) {
console.log(getNumber1() + getNumber2());
}
addTwoNums(specificNum, specificNum); // izvadītais numurs ir 84
addTwoNums(specificNum, randomNum); // izvadītais numurs ir 42 + kāds nejaušs numurs
Tīras funkcijas (jeb PURE funkcijas) un blakus efekti Vēl viena funkcionālās programmēšanas koncepcija ir tīras funkcijas.
Tīra funkcija atgriež tieši tādu pašu rezultātu, kamēr tai tiek doti tās pašas vērtības.
Tīras funkcijas piemērs ir addTwoNums() funkcija no iepriekšējās sadaļas:
function addTwoNums(a, b) {
console.log(a + b)
}
addTwoNums(5,6); // 11
… izvade vienmēr būs tāda pati.
Vēl viens noteikums, lai funkcija tiktu uzskatīta par tīru, ir tā, ka tā nedrīkst radīt blakus efektus. Blakus efekts ir jebkurš gadījums, kad funkcija veic izmaiņas ārpus sevis.
Tas ietver:
mainīt ārpus funkcijas esošo mainīgo vērtības vai pat paļauties uz ārējiem mainīgajiem
izsaukt Pārlūka API (pat console pats!)
izsaukt Math.random() – jo vērtība nav uzticami atkārtojama
Tīras un netīras funkciju tēma var kļūt nedaudz sarežģīta.
Šobrīd pietiek zināt, ka šī koncepcija eksistē un ka tā ir saistīta ar funkcionālo programmēšanu.
Atbildēt
Lai komentētu, jums jāpiesakās sistēmā.