Unde rulează JavaScript
Lectură estimată: 14 minute
Estimare pentru text, la un ritm de 180 de cuvinte pe minut. Timpul pentru analizarea codului, exerciții și proiecte se adaugă separat și depinde de ritmul tău.
Ce construim în această lecție
În această lecție pregătești baza unui calculator de buget pentru un proiect fictiv. Nu introducem încă formularul și nici validarea sumelor. Construim mai întâi o pagină care poate încărca un fișier JavaScript, modifica un mesaj și explica prin consolă ce s-a întâmplat. Dacă această fundație nu funcționează, orice funcție de calcul adăugată ulterior va fi greu de verificat. Scopul este să poți urmări traseul dintre fișierul salvat, browser și rezultatul observat.
La final vei avea trei fișiere: index.html pentru structură, styles.css pentru prezentare și app.js pentru comportament. Vei porni pagina printr-un server local, vei verifica răspunsurile HTTP și vei provoca deliberat câteva erori într-o copie a laboratorului. Fiecare eroare are un simptom, o explicație și o corectură. Nu lucrăm într-un proiect de producție și nu introducem informații personale.
Păstrează un registru cu patru coloane: schimbarea făcută, rezultatul așteptat, rezultatul observat și explicația. Prima dată scrie ce crezi că se va întâmpla, apoi rulează experimentul. Această ordine te obligă să formulezi o ipoteză. Dacă scrii numai după ce ai văzut rezultatul, riști să confunzi recunoașterea unui mesaj cu înțelegerea cauzei lui.
Limbajul și mediul în care îl execuți
JavaScript este un limbaj de programare. Browserul este unul dintre mediile care îl execută și îi pune la dispoziție obiecte pentru lucrul cu pagina. Node.js este un alt mediu, folosit inclusiv pentru programe în terminal și aplicații server. Lista nu se reduce la aceste două exemple. Pentru început ne interesează să separăm regulile limbajului de facilitățile oferite de mediul ales.
Un calcul precum 500 + 1200 + 300 nu are nevoie de o pagină. În schimb, document.querySelector folosește documentul expus de mediul browserului. Dacă același fișier este executat direct în Node.js, nu primește automat pagina deschisă într-o altă aplicație. Numele fișierului poate fi identic, dar contextul de execuție este diferit. Când raportezi o eroare, spune întotdeauna unde ai rulat codul.
Imaginează-ți că ai o rețetă și două bucătării. Instrucțiunile despre ordine și cantități rămân aceleași, însă echipamentele disponibile diferă. Analogia are o limită: programele nu improvizează când un obiect lipsește, ci urmează regulile limbajului și produc un rezultat sau o eroare. De aceea nu este suficient să spui „codul este JavaScript”; trebuie să precizezi și mediul necesar.
HTML, CSS și JavaScript au responsabilități distincte
HTML descrie structura documentului: titlul, paragrafele și zonele de conținut. CSS controlează prezentarea. JavaScript adaugă comportamentul pe care îl programăm. Nu orice pagină are nevoie de JavaScript pentru a fi utilă. În laborator, explicația proiectului rămâne vizibilă chiar dacă scriptul nu se încarcă. Numai mesajul de stare depinde de execuția lui.
Această separare face diagnosticul mai clar. Dacă titlul lipsește complet, verifici documentul și adresa paginii. Dacă textul există, dar aspectul nu corespunde, investighezi stilurile. Dacă prezentarea este corectă, însă mesajul nu se schimbă, urmărești scriptul. Pot exista probleme care combină mai multe straturi, dar această ordine îți oferă un punct de pornire.
Nu vom transforma textul „script neinițializat” într-un mesaj de succes doar pentru că arată mai bine. Starea inițială trebuie să descrie sincer ce știm înainte de execuție. Ulterior, aplicațiile au stări de încărcare, succes și eroare. Aici exersăm aceeași disciplină într-un exemplu mic: afișăm confirmarea numai după ce codul ajunge efectiv la operațiunea respectivă.
Pregătirea directorului de lucru
Creează un director nou numit laborator-js-01. În el salvează cele trei fișiere ale lecției cu un editor de text simplu sau un editor de cod. Verifică extensiile reale: app.js.txt nu este același nume cu app.js. Activarea afișării extensiilor în exploratorul de fișiere poate clarifica această greșeală pe Windows.
Fișierele se salvează în UTF-8, pentru ca diacriticele să fie păstrate. Nu copia marcajele care delimitează blocurile de cod din lecție. De exemplu, linia cu numele fișierului este o indicație pentru tine, nu o instrucțiune JavaScript. Începe prin salvarea tuturor fișierelor înainte de a deschide pagina; o filă deschisă în editor nu înseamnă că informația există deja pe disc.
În această etapă nu ai nevoie de un framework, un cont de găzduire sau de un proces de compilare. Mai puține componente înseamnă mai puține surse posibile ale erorilor. Vom adăuga complexitate când apare o nevoie pe care o putem explica, nu pentru că un proiect demonstrativ trebuie să semene de la început cu o aplicație mare.
Fișierul index.html
Documentul de mai jos are un singur titlu principal și un paragraf identificat prin id. Identificatorul stare este legătura dintre structura HTML și codul care o va modifica. Stilurile și scriptul sunt fișiere distincte, aflate în același director. Atributul lang indică limba documentului, iar viewport permite o prezentare potrivită pe ecrane înguste.
<!doctype html>
<html lang="ro">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Primul laborator JavaScript</title>
<link rel="stylesheet" href="styles.css">
<script src="app.js" defer></script>
</head>
<body>
<main>
<h1>Calculator de buget: pregătirea</h1>
<p>Proiect fictiv. În această lecție verificăm încărcarea scriptului.</p>
<p id="stare">Script neinițializat.</p>
<noscript>JavaScript este dezactivat în acest browser.</noscript>
</main>
</body>
</html>Textul din noscript ajută când executarea scripturilor este dezactivată. El nu apare automat pentru orice eroare din app.js. Un fișier lipsă sau o greșeală de sintaxă nu este același lucru cu dezactivarea JavaScript. Păstrează această distincție când verifici o pagină: mecanismele de rezervă trebuie proiectate pentru condițiile pe care le pot detecta.
Fișierul styles.css
Stilurile sunt intenționat puține. Limităm lățimea textului, oferim spațiere și permitem împărțirea șirurilor lungi. Nu adăugăm animații sau elemente decorative care ar îngreuna observarea mesajului. Pe parcursul exercițiilor, aspectul paginii trebuie să rămână suficient de constant încât schimbarea textului să fie ușor de văzut.
* { box-sizing: border-box; }
body {
margin: 0;
padding: 1rem;
font: 1rem/1.6 system-ui, sans-serif;
color: #202838;
background: #f4f6fb;
}
main {
max-width: 46rem;
margin: 2rem auto;
padding: 1.5rem;
background: white;
border: 1px solid #ccd3df;
border-radius: 0.75rem;
}
h1 { font-size: 1.8rem; line-height: 1.2; }
p { overflow-wrap: anywhere; }
#stare { padding: 1rem; background: #edf2ff; }Salvează și acest fișier înainte de test. Dacă aspectul nu se aplică, nu modifica imediat JavaScriptul. Verifică mai întâi calea styles.css și răspunsul resursei. O eroare CSS poate face pagina mai puțin plăcută, dar nu demonstrează că scriptul nu rulează. În laborator vom observa separat încărcarea fiecărui fișier.
Fișierul app.js, explicat pe rând
Codul pornește cu un mesaj în consolă. Apoi caută elementul și verifică dacă există. Dacă lipsește, aruncă o eroare cu o explicație precisă. Dacă există, îi schimbă textul și confirmă în consolă finalizarea. Folosim const pentru referința la element; lecția următoare dezvoltă variabilele și tipurile.
console.log("Pornire laborator JS.");
const stare = document.querySelector("#stare");
if (stare === null) {
throw new Error("Lipsește elementul #stare din document.");
}
stare.textContent = "Script încărcat. Laborator pregătit.";
console.log("Inițializare încheiată.");querySelector întoarce primul element care corespunde selectorului sau null dacă nu găsește unul. Semnul # indică un identificator CSS. Nu căutăm textul paragrafului și nu căutăm numele unei variabile din editor. Căutăm în structura documentului pe care browserul îl are disponibil în acel moment.
Verificarea explicită este utilă aici deoarece elementul este obligatoriu pentru exercițiu. Dacă am scrie doar „dacă există, modifică-l”, pagina ar putea rămâne în starea inițială fără o explicație clară. În alte componente, absența unui element poate fi acceptabilă. Alegerea trebuie să reflecte contractul componentei, nu preferința de a ascunde erorile.
textContent introduce text. Nu interpretează șirul ca un fragment HTML. Dacă mesajul ar conține caractere precum < și >, ele ar rămâne text vizibil. În această lecție nu avem input de utilizator, dar alegerea pregătește un obicei util pentru calculatorul de buget: afișăm valori și mesaje fără să le transformăm inutil în markup.
De ce folosim defer
Pentru acest script clasic extern, defer permite descărcarea în timpul parsării HTML și amână execuția până după parsarea documentului. Nu înseamnă că toate imaginile și toate resursele paginii s-au terminat de încărcat. Ordinea ne permite să căutăm paragraful din body chiar dacă elementul script se află în head.
Fără defer, un script clasic extern aflat aici poate rula înainte ca parserul să fi ajuns la paragraful nostru. Nu orice script fără defer este greșit: un calcul care nu folosește elementele respective are alte condiții. Problema concretă este dependența dintre cod și existența elementului pe care îl caută.
Nu înlocui defer cu async presupunând că sunt sinonime. async nu oferă aceeași garanție de execuție după parsarea documentului. Scripturile module au propriul comportament; le vom aborda separat. Pentru laborator păstrează exact forma externă cu defer și investighează doar variațiile cerute, într-o copie.
Pornește laboratorul prin HTTP local
Dacă ai Python 3 disponibil, deschide terminalul în directorul laborator-js-01 și pornește un server local. Pe Windows, într-o instalare care oferă launcherul py, poți folosi comanda de mai jos. Pe Linux sau macOS folosește python3 în loc de py -3. Dacă Python lipsește, utilizează un server de dezvoltare de încredere deja instalat, cu aceeași rădăcină de documente.
py -3 -m http.server 18771 --bind 127.0.0.1Deschide http://127.0.0.1:18771/index.html în browser. Terminalul serverului rămâne deschis. Portul este ales pentru laborator, nu are o semnificație specială. Dacă este ocupat, alege altul și modifică adresa în consecință. Serverul demonstrativ nu este o soluție de publicare în producție.
Acest exemplu cu script clasic poate funcționa și prin deschiderea fișierului local, dar folosim HTTP ca să putem observa clar răspunsurile resurselor. Nu generaliza rezultatul la module, fetch sau orice alt API. Un exercițiu care merge prin file nu demonstrează că toate etapele viitoare vor avea același comportament.
Ce verifici în browser
Deschide instrumentele pentru dezvoltatori din meniul browserului. În Network, reîncarcă pagina și identifică index.html, styles.css și app.js. Pentru fiecare verifică adresa, statusul și conținutul răspunsului. Dacă serverul întoarce o pagină HTML în locul unui script, un status 200 nu este suficient pentru a declara resursa corectă.
În Console urmărește cele două mesaje din cod. În pagină trebuie să apară „Script încărcat. Laborator pregătit.”. Aceste trei observații răspund la întrebări diferite: fișierul a fost cerut, codul a ajuns la punctele marcate și documentul a fost modificat. Păstrează diferența dintre ele în notițe.
Pentru o verificare suplimentară, deschide fișierul app.js în panoul Sources și pune un breakpoint pe linia care atribuie textContent. Reîncarcă pagina, inspectează valoarea stare și continuă execuția. Un breakpoint îți permite să observi starea programului într-un punct precis; un console.log îți oferă o urmă textuală. Nu trebuie să alegi unul pentru totdeauna.
Experimentul 1: fișierul nu este găsit
Într-o copie a laboratorului, schimbă src din app.js în app-lipsa.js, fără să creezi acel fișier. Reîncarcă pagina. Textul ar trebui să rămână în starea inițială, iar Network să arate cererea nereușită. Mesajele definite în app.js nu mai sunt dovezi noi ale acestei încărcări; golește consola sau delimitează clar încercările.
Rezolvarea este să restabilești calea corectă, nu să adaugi setTimeout în JavaScript. Codul care nu a fost încărcat nu poate fi reparat printr-o instrucțiune din același fișier. Scrie în registru diferența dintre „fișierul lipsește” și „fișierul există, dar conține o eroare”. Sunt etape distincte ale traseului.
Experimentul 2: sintaxă invalidă
Restabilește mai întâi laboratorul funcțional. Apoi elimină deliberat ghilimeaua de închidere a primului mesaj din app.js. Salvează și reîncarcă. Fișierul poate fi descărcat cu succes, dar parserul JavaScript nu îl poate interpreta. În această situație, nici mesajul de la începutul aceluiași script nu este executat.
Repară ghilimeaua și repetă testul. Nu memora formularea exactă a erorii, deoarece poate diferi între browsere. Recunoaște categoria și poziția indicată. Uneori locul unde parserul detectează problema este după greșeala reală. Citește și liniile din jur, în special perechile de ghilimele, paranteze și acolade.
Experimentul 3: elementul obligatoriu lipsește
Cu fișierele din nou corecte, schimbă id="stare" în id="mesaj" numai în HTML. Acum scriptul pornește și primul console.log apare. Căutarea întoarce null, iar eroarea noastră oprește restul acestui script. Mesajul „Inițializare încheiată.” nu trebuie să apară pentru această execuție.
Corectura este să aliniezi identificatorul și selectorul. Nu elimina verificarea doar ca să dispară mesajul. Ea a descoperit exact nepotrivirea pe care voiam să o vedem. În raport explică de ce avem dovada pornirii, dar nu și a finalizării, spre deosebire de eroarea de sintaxă din experimentul anterior.
Experimentul 4: schimbarea din consolă nu rescrie fișierul
În consola paginii funcționale, execută instrucțiunea următoare. Observă mesajul nou, apoi reîncarcă pagina fără să modifici app.js.
document.querySelector("#stare").textContent = "Schimbare temporară.";După reîncărcare revine mesajul produs de fișier. Ai modificat documentul curent din memoria browserului, nu sursa salvată în editor. Această diferență explică multe situații în care un începător spune că „browserul nu păstrează corectura”. Pentru o schimbare persistentă în proiect, modifică fișierul potrivit, salvează și reîncarcă.
Consola este un loc de execuție, nu un spațiu în care orice text copiat este inofensiv. Pentru această lecție tastează instrucțiunile pe care le explicăm, în pagina laboratorului. Nu rula cod primit de la persoane necunoscute în pagini unde ești autentificat și nu folosi consola ca depozit pentru secrete.
Comparație opțională cu Node.js
Dacă ai deja Node.js instalat, salvează acest fragment într-un fișier mediu.js și rulează node mediu.js în terminal. Execută aceleași instrucțiuni și în consola paginii laboratorului, într-un context obișnuit, fără biblioteci care adaugă obiecte globale.
console.log(500 + 1200 + 300);
console.log(typeof document);
console.log(typeof process);Calculul produce 2000 în ambele medii. În pagina browserului, document este disponibil, iar process nu este în mod obișnuit un global oferit de browser. În Node.js, process este disponibil, iar document nu este furnizat ca DOM al unei pagini. Folosim typeof pentru această comparație fără a accesa direct un identificator absent.
Nu instala Node.js numai pentru a trece de această lecție dacă vrei momentan să lucrezi exclusiv în browser. Comparația este opțională. Dacă o execuți, notează versiunea și rezultatele reale. Nu concluziona că toate API-urile sunt diferite: mediile au și facilități comune, iar compatibilitatea evoluează.
Exerciții cu repere de rezolvare
Prima sarcină este să schimbi mesajul final în „Laboratorul meu este pregătit.” fără să modifici identificatorul. Rezolvarea se află în atribuirea textContent din app.js. Verifică faptul că schimbarea persistă după reload și că Network livrează fișierul salvat, nu o copie veche din alt director.
A doua sarcină este să explici două cazuri care arată identic în pagină: script lipsă și element cu identificator greșit. Reperele sunt diferite în instrumente. În primul caz, cererea scriptului eșuează și codul nu pornește. În al doilea, resursa se încarcă, primul mesaj apare și verificarea elementului produce eroarea. Un screenshot al paginii singure nu este suficient.
A treia sarcină este să atribui mesajului textul literal „<strong>Pregătit</strong>”. Cu textContent, parantezele unghiulare și numele elementului trebuie să fie afișate ca text, fără a crea un element strong în acel paragraf. Rezolvarea nu cere innerHTML. Scopul este să verifici mecanismul ales, nu să obții text îngroșat.
A patra sarcină este să explici ce se întâmplă dacă oprești serverul și încerci o cerere nouă cu cache-ul dezactivat. Nu confunda pagina deja încărcată cu accesibilitatea serverului. Documentul existent poate rămâne vizibil; o cerere nouă nu va primi răspuns de la procesul oprit. Încheie exercițiul repornind serverul și verificând revenirea.
Criterii de finalizare și pasul următor
Lecția este încheiată când poți recrea cele trei fișiere, identifica resursele încărcate și explica cele trei categorii de eroare: încărcare, sintaxă și execuție. Predă registrul cu cel puțin o observație pentru fiecare experiment și o copie funcțională a laboratorului. Nu lăsa versiunea cu erori drept singura variantă salvată.
Timpul afișat pentru lecție estimează lectura prozei. Configurarea mediului, tastarea codului și depanarea se adaugă separat. Pentru prima parcurgere rezervă o sesiune în care poți opri și relua experimentele fără presiunea de a termina într-un număr fix de minute. În lecția următoare folosim această bază pentru variabile, tipuri și conversii, înainte să construim totalul bugetului.
Documentație verificată la 20 octombrie 2026
Materiale pentru această lecție
Ți-a plăcut lecția? Continuă cursul complet
Ai citit o lecție gratuită. Celelalte lecții, aplicațiile practice și materialele se deblochează odată cu cursul.
99 lei
Plată unică, acces pe viață la toate cele 8 lecții.
Vezi ce conține cursul →