Sunteți pe pagina 1din 18

Programarea interfețelor grafice

 Curs 3

JavaScript
Programarea obiectuală Crearea obiectelor JavaScriptDestructurarea obiectelorClonarea obiectelorObiecte în notație  JSONLocal Storage

Programarea obiectuală în JavaScript

Obiecte în notație literală


În exemplele din cursurile precedente s-au folosit date de două tipuri: numere și șiruri de caractere. Totuși au mai fost și alte expresii care conțin
clasicele notații cu punct folosite în limbajele care suportă programarea obiectuală. Exemple:

console.log(); sau document.querySelector();

Uneori expresiile au fost chiar mai complicate, ca în cazul modificării dinamice a stilurilor:

const blocMesaj = document.querySelector("#mes");

blocMesaj.style.color = "#FFFF00"; // putea fi "yellow" sau "rgb(255,255,0)"

blocMesaj.style.backgroundColor = "rgba(150,0,0,0.5)";

blocMesaj.style.backgroundImage = "url('imagini/foc_mic.png')";
Obiectele în notație literală, menționate deja, pot fi definite în JavaScript ca fiind colecții de perechi de forma cheie: valoare, ambele având valori
precizate. Perechile de forma cheie: valoare mai poartă numele de câmpuri sau proprietăți ale unui obiect.
Cât despre utilitatea practică a codificării informațiilor folosind obiecte, aceasta poate fi evidențiată făcând analiza unui caz concret.
Astfel se propune realizarea unei aplicații care să fie o variantă digitală a unui caiet al dirigintelui. Mai precis caietul dirigintelui clasei a 8-a B din
Școala Generală Măgura.
O astfel de aplicație ar trebui să memoreze elevii unei clase. Dar nu numai numele și prenumele ci și alte date, necesare pentru a realiza ulterior
diverse activități specifice activității de diriginte.
Soluția pe care ar propune-o un informatician ar fi crearea pentru fiecare elev a unui obiect. Mai mult, obiectele astfel obținute ar trebui să fie elemente
ale unui șir de obiecte denumit clasa8B, după numele clasei.
De ce? Pentru că JavaScript dispune de un set complet de funcții care permit realizarea ușoară a unui ansamblu de prelucrări asupra șirurilor de
valori. Ori elementele șirurilor de valori pot fi și obiecte!
O variantă a modelului folosit pentru înregistrarea elevilor în caietul dirigintelui ar putea fi următoarea:

const clasa8B = [ // Începe construirea unui șir de obiecte

{ // Primul obiect, clasa8B[0]

nume: "Avram",

prenume: "Laura",

dataNasterii: "2007-06-19", // Formatul standard pentru data calendaristică: an-lună-zi

telefon: "0745563878",

email: "avalaura07@gmail.com",

emailParinte: "avram.teodor@apacom.ro",

telParinte: "0744395984",
adresa: "Str. Ulmilor nr. 12, com. Măgura, jud. Timiș",

gen: "F",

note: [

{materie: "Fizică", data: "2021-02-21", nota: 8}, // notație: clasa8B[0].note[0]

{materie: "Chimie", data: "2021-03-1", nota: 9}, // clasa8B[0].note[1]

{materie: "Fizică", data: "2021-03-5", nota: 9},

{materie: "Matematică", data: "2021-03-12", nota: 7},

{materie: "Engleză", data: "2021-04-1", nota: 10},

],

absente: [

{data: "2021-03-2", materie: "Limba Română"}, // notație: clasa8B[0].absente[0]

{data: "2021-03-3", materie: "Matematică"}, // clasa8B[0].absente[1]

{data: "2021-04-3", materie: "Fizică"},

],

},

{ // Al doilea obiect, clasa8B[1]


nume: "Barbu",

prenume: "Mircea",

dataNasterii: "2007-03-08",

telefon: "0723228567",

email: "barbumi14@yahoo.com",

emailParinte: "barbu.mircea@htt.ro",

telParinte: "0733562098",

adresa: "Str. Decebal nr. 2, com. Măgura, jud. Timiș",

gen: "M",

note: [{...}, {...}, {...}, {...}],

absente: [{...}, {...}],

},

... // și încă 24!

];

Modelul propus este bazat deci pe memorarea datelor aplicației în șiruri de obiecte: șirul elevilor (variabila clasa8B), șirul notelor unui elev sau șirul
absențelor unui elev. Pentru realizarea prelucrărilor de șiruri de valori, în cursul viitor va fi prezentat un set de funcții JavaScript care va permite
realizarea fără efort a tuturor prelucrărilor necesare. Exemple de prelucrări:

 căutarea unui obiect într-un șir (funcția find());


 preluarea într-un șir nou doar a elementelor care satisfac o condiție impusă (operație denumită filtrare, realizată folosind funcția filter());
 prelucrarea fiecărui element dintr-un șir dat prin apelarea repetată a unei funcții (funcția map()). Funcția map() are ca argument o funcție care
operează asupra unui element din șir și returnează o formă modificată a acestuia. Funcția map() va genera astfel un șir nou;
 ordonarea unui șir de valori (funcția sort());
 reducerea unui șir de valori la o singură valoare. Funcția utilizată se numește reduce() și apelul ei produce fie o sumă de valori numerice, fie
un șir de caractere realizat după o regulă impusă. Șirul de caractere astfel creat conține frecvent o reprezentare tabelară a obiectelor conținute
într-un șir de valori (un element HTML <table>) sau o reprezentare a acestora sub forma unei liste (o listă ordonată, <ol>, sau neordonată, <ul>).

Crearea obiectelor JavaScript


Crearea obiectelor se poate face după modelul următor:

let ciprian = {}; // Obiect vid (deocamdată)

let marius = {

nume: 'Popescu',

prenume: 'Marius'

};

// Caracterele ' (apostrof) pot fi inlocuite cu " (ghilimele).

console.log(marius); // {nume: "Popescu", prenume: "Marius"}

În cazul obiectului ciprian, acesta a fost declarat dar nu conține proprietăți. După declararea unui obiect, setul de proprietăți ale acestuia poate fi
extins scriind:
marius.varsta = 23; // marius va avea 3 câmpuri: nume, prenume și varsta.

ciprian.nume = "Avram";

ciprian.prenume = "Ciprian";

ciprian.varsta = 27; // la fel și ciprian.

Aceleași proprietăți pot fi adăugate folosind o sintaxă alternativă:

marius['varsta'] = 23; // Se pot folosi ghilimele in loc de apostroafe

ciprian['nume'] = "Avram";

ciprian['prenume'] = "Ciprian";

ciprian['varsta'] = 27;

Dacă se folosește această sintaxă, numele proprietății (cheia, eng. key) poate fi conținut întro variabilă:

let prop = 'prenume';

ciprian[prop] = "Ciprian";

prop = 'varsta';

marius[prop] = 25;

Bazat pe cele scrise se poate scrie următorul exemplu fundamental:


<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>

<title>Obiecte</title>

</head>

<body>

<h2>Utilizarea obiectelor</h2>

<script>

"use strict";

let marius = {

nume: 'Popescu',

prenume: 'Marius'

};
let ciprian = {};

let mircea = new Object();

marius.varsta = 23;

ciprian.nume = "Avram";

ciprian.prenume = "Ciprian";

ciprian.varsta = 27;

mircea.nume = "Petrescu";

let prop = 'prenume';

mircea[prop] = "Mircea";

prop = 'varsta';

mircea[prop] = 25;

console.log(ciprian);

console.log(mircea);
</script>

</body>

</html>

Rezultat afișat în consolă:

Observație: Directiva "use strict" elimină posibilitatea utilizării unei variabile nedeclarate. Exemplu:
"use strict";

a = 12; // Eroare! Variabila a nu este declarată și este prezentă directiva "use strict"

Pentru a șterge o proprietate a unui obiect se poate folosi delete:

delete mircea.prenume;

sau

let cheie = varsta;

delete mircea[cheie];

Din cele expuse se poate observa că obiectele permit practic atribuirea unui nume unic unui set de valori.
Observație: Pentru a afișa proprietățile unui obiect predefinit se poate scrie un ciclu for, astfel:

for (let cheie in marius) {

console.log(cheie + ": " + marius[cheie] );

}
Destructurarea obiectelor
Crearea obiectelor are ca scop gruparea caracteristicilor unei entități. În aplicații avem frecvent nevoie și de extragerea în variabile separate a valorilor
unor proprietăți.
Acest lucru nu pune probleme, deoarece putem scrie:

const numeCursant = marius.nume;

const prenumeCursant = marius.prenume;

În JavaScript ES6 se poate folosi și o scriere mai compactă:

const {nume, prenume} = marius; // const sau let, dupa caz

Scriind astfel, preluăm într-un set de variabile valorile unor câmpuri. Acțiunea poartă numele de destructurare a obiectului marius.
Este important însă să remarcăm faptul că denumirile variabilelor astfel create (nume, prenume) trebuie să coincidă cu denumirile câmpurilor obiectului
supus destructurării ale căror valori trebuie preluate.

Clonarea obiectelor
Se consideră declarația următoare:

let marius = {

nume: 'Popescu',

prenume: 'Marius',

varsta: 23

};

Dacă dorim o copie a obiectului (o clonă) se poate scrie:

let clonaMarius = {};

for (let cheie in marius) {

clonaMarius[cheie] = marius[cheie];

Desigur, în acest caz banal se putea scrie și așa:

let clonaMarius = {

nume: marius.nume,

prenume: marius.prenume,
varsta: marius.varsta

};

În JavaScript ES6 se poate însă scrie și mai simplu, așa:

let clonaMarius = { ...marius }; // Folosim operatorul "..." (spread operator)

În niciun caz însă:

let clonaMarius = marius;

deoarece marius și clonaMarius sunt adresele din memorie ale unor obiecte. Ori în JavaScript, atribuirea:

let clonaMarius = marius;

nu va determina crearea unei copii a obiectului marius într-o altă zonă din memorie, deci crearea unui nou obiect. Se va copia doar adresa conținută în
celula de memorie marius în celula clonaMarius.
Interesul creării unor clone ale unor obiecte derivă din faptul că în programarea JavaScript actuală privilegiem considerarea obiectelor aplicației ca
fiind invariabile (eng. immutables). Deci modificarea unui obiect va consta de fapt în crearea sistematică a unui nou obiect care va conține
modificările dorite. În acest fel, în cazul în care rezultatele obținute sunt eronate, vom putea examina fiecare pas realizat. Este de presupus ca, o astfel
de abordare, să implice realizarea unor clone ale obiectelor supuse prelucrării.

Obiecte în notație JSON
JSON este denumirea unui mod de reprezentare a informațiilor destinat stocării și transportului acestora. JSON este o prescurtare a
denumirii JavaScript Object Notation.
Exemplu:

'{"nume":"Popescu", "prenume":"Marius", "varsta":30, "casatorit":null}'

Șirul de caractere astfel scris reprezintă un obiect JavaScript în notație JSON.


Aparent diferența dintre un obiect în notație JSON și același obiect JavaScript în notație literală este dată de notarea diferită a proprietăților
(perechi cheie-valoare), respectiv de încadrarea cheilor între ghilimele. Dar nu este așa deoarece JavaScript permite încadrarea cheilor între ghilimele
și în cazul obiectelor în notație literală. Exemplu:

// masAUDI este tot un obiect în notație literala

const masAUDI = {

constructor: "Audi",

"modelul de baza": "A4",

"anul fabricatiei": 2020

};

În acest mod se pot utiliza și denumiri de chei formate din mai multe cuvinte despărțite prin spații. Deci singura diferență esențială dintre notația literală
și formatul JSON constă în perechea de apostroafe care încadrează obiectul și care fac ca orice reprezentare a unor informații folosind formatul JSON
să fie de fapt un șir de caractere. Dar trebuie totuși remarcat că toate șirurile de caractere sunt încadrate între ghilimele (nu apostroafe!) iar cheile sunt
întotdeauna încadrate între ghilimele.
Codificarea în și din JSON a obiectelor JavaScript se realizează prin utilizarea funcțiilor specializate JSON.stringify() respectiv JSON.parse().
Exemple:

// Un obiect în notație literala

const masAudi = {

constructor: "Audi",

model: "A4",
anFabricatie: 2020

};

// Reprezentarea aceluiasi obiect in format JSON

const masJSON = JSON.stringify(masAudi); // masJSON e un șir de caractere!

// Conversia inversa, din JSON in obiect JavaScript

const unAltAudi = JSON.parse(masJSON);

Local Storage
În contextul aplicaților care vor fi scrise, formatul JSON va fi utilizat intens deoarece el va permite păstrarea setului de date al aplicației într-o zonă de
memorie alocată browser-ului denumită localStorage. Desigur, dacă browser-ul ar permite exploatarea discului calculatorului n-am avea nevoie
de localStorage. Se știe însă că, din considerente de securitate, scripturile JavaScript rulate în browser nu pot accesa resurse ale calculatorului. Și cea
mai importantă dintre resurse ar fi discul, deoarece ne-ar permite păstrarea datelor între două rulări ale aplicației.
Deci posibilitatea stocării unor date în localStorage este esențială. Sigur, dacă scriem o aplicație care se rulează în browser și nu accesează o resursă
externă (un server) pentru a-și păstra datele.
Datele păstrate în localStorage reprezintă starea aplicației. La repornirea aplicației, una dintre primele activități ale acesteia va fi restaurarea stării prin
citirea informațiilor memorate în localStorage. Evident, pentru a permite acest lucru, datele stocate în localStorage nu sunt distruse dacă se iese din
aplicație. Practic dacă am asimila browser-ul cu un calculator, localStorage ar fi discul acestuia. Și continuând analogia, JavaScript și fereastra
browser-ului ar fi limbajul de programare respectiv ecranul acestuia.
Mărimea spațiului de stocare oferit de localStorage este de 5MO/aplicație (5 megaocteți, deci aprox. 5 milioane de caractere). Deci destul de
"încăpător", pentru aplicațiile obișnuite.

Scrierea în localStorage se realizează folosind localStorage.setItem().

localStorage.setItem("clasa8B", JSON.stringify(clasa8B));

Deci cu o singură comandă, șirul de obiecte clasa8B va fi memorat în localStorage! Dar trebuie să remarcăm că, în localStorage, o aplicație poate
scrie doar perechi cheie - valoare, valoarea fiind obligatoriu un șir de caractere. Dacă trebuie memorate mai multe valori, acestea pot fi memorate
folosind mai multe perechi cheie - valoare sau valorile pot fi memorate într-un obiect JavaScript având o structură mai complexă.

Citirea unui șir de caractere din localStorage se realizează folosind localStorage.getItem().

const sirMemo = localStorage.getItem("clasa8B");

const clasa8B = JSON.parse(sirMemo); // Reconstituim șirul de obiecte JavaScript

Ștergerea din localStorage a unei perechi cheie - valoare se realizează folosind localStorage.removeItem().

localStorage.removeItem("cheie_de_sters");

Ștergerea din localStorage a tuturor perechilor cheie - valoare înregistrate de aplicație în localStorage se realizează folosind localStorage.clear().


localStorage.clear();

Verificarea prezenței în localStorage a unei perechi cheie - valoare înregistrată de aplicație se realizează astfel:

if(localStorage.getItem("cheie_cautata") === null) {...}

TOP

S-ar putea să vă placă și