IlmHamroh
JavaScript Full-stack/8-qism. JavaScript asoslari6/61-dars15 daqiqa
Mundarija (29)

JavaScript var: nega undan voz kechildi va eski kodda uni qanday o'qish kerak

Qisqacha: var — o'zgaruvchi e'lon qilishning eski usuli. U bir nomni ikki marta e'lon qilishga ruxsat beradi, e'londan oldin xato o'rniga undefined beradi, { } blokini tanimaydi va brauzerda window obyektiga yoziladi. Shu sababli 2015-yildan beri let va const ishlatiladi. Yangi kodda var yozmang, lekin eski kodda uni uchratasiz — o'qiy olishingiz kerak.

Bu darsda

  • var qanday yozilishini va let/const dan qaysi 4 jihati bilan farq qilishini bilasiz.
  • var bilan bog'liq jim xatolarni (xato xabarisiz buziladigan kodni) taniysiz.
  • Blok va funksiya ko'rinish doirasi (scope) farqini tushuntira olasiz.
  • Eski koddagi var ni let yoki const ga xavfsiz almashtira olasiz.

Oldin bilishingiz kerak: let va const bilan o'zgaruvchilar, Sintaksis asoslari.

1. Nega bu kerak?

O'tgan darsda o'zgaruvchini let va const bilan yaratdik. Lekin internetda JavaScript kodini qidirsangiz, ko'pincha boshqacha yozuvni ko'rasiz:

js
var narx = 5000;
console.log(narx); // 5000

Bu var — o'zgaruvchi yaratishning eski usuli. JavaScript 1995-yilda paydo bo'lgan. Keyingi 20 yil davomida o'zgaruvchi yaratishning yagona yo'li var edi. let va const faqat 2015-yilda, ES2015 (ES6 deb ham ataladi) versiyasi bilan qo'shildi.

Nega var ni butunlay olib tashlashmagan? Chunki dunyodagi millionlab saytlar u bilan yozilgan. var o'chirilsa, bu saytlar ertasiga ishlamay qoladi. JavaScript'ning oltin qoidasi: "eski saytlarni buzma".

Demak, siz var ni ko'p uchratasiz: eski darsliklarda, forumlardagi javoblarda, ishga kirgan kompaniyangizning 10 yillik kodida. Bu darsning maqsadi — var ni yozishni emas, uni o'qish va tuzoqlarini tanishni o'rgatish.

2. var qanday yoziladi

Tashqi ko'rinishdan var xuddi let ga o'xshaydi:

js
var shahar = "Andijon";
console.log(shahar); // Andijon

shahar = "Farg'ona";
console.log(shahar); // Farg'ona

E'lon qilish, tayinlash, qayta tayinlash — hammasi let dagidek. Oddiy holatlarda farq ko'rinmaydi ham.

Farq — chetki holatlarda. var ning to'rtta xususiyati bor, ularning har biri xatolarga yo'l ochadi. Keling, birma-bir ko'ramiz.

3. 1-muammo: bir nomni ikki marta e'lon qilish

let bilan bitta nomni ikki marta e'lon qilsangiz, JavaScript darhol to'xtatadi. var bilan esa:

js
var jami = 50000;
console.log(jami); // 50000

var jami = 0;
console.log(jami); // 0

Hech qanday xato yo'q. Ikkinchi var jami birinchisini jimgina "bosib" ketdi.

Kichik faylda bu muammo emas. Endi tasavvur qiling: 500 qatorli faylda 20-qatorda Malika var jami yozgan — kunlik savdo summasi. 430-qatorda Jasur ham var jami yozdi — boshqa hisob uchun. Jasurning kodi Malikaning summasini o'chirib yubordi. Hech kim ogohlantirmadi. Xato faqat kun oxiridagi hisobotda chiqadi.

let bilan esa xuddi shu holat darhol to'xtatiladi:

js
let jami = 50000;
let jami = 0;
text
SyntaxError: Identifier 'jami' has already been declared

Xato xabari — dasturchining do'sti. U muammoni kod ishga tushishidan oldin ko'rsatadi. var esa jim turadi.

Tekshirib ko'ring: Konsolda nima chiqadi?

js
var mijoz = "Ali";
var mijoz = "Vali";
console.log(mijoz);
Javob

Vali. var qayta e'lon qilishga ruxsat beradi — ikkinchi e'lon birinchisining qiymatini almashtiradi, xato chiqmaydi. let bo'lganda SyntaxError chiqib, kod umuman ishlamas edi.

4. 2-muammo: e'londan oldin undefined

O'tgan darsda ko'rdik: let bilan e'lon qilingan o'zgaruvchini e'londan oldin ishlatib bo'lmaydi. var da-chi?

js
console.log(taom);
var taom = "osh";
console.log(taom);

Konsolda:

text
undefined
osh

Birinchi qatorda xato yo'q! JavaScript taom ni taniydi, lekin qiymati — undefined ("qiymat hali berilmagan").

4.1 Bu qanday bo'ladi?

"Kod yuqoridan pastga bajariladi" dedik-ku? Bu qoida hali ham rost. Lekin JavaScript kodni bajarishdan oldin faylni bir marta tez ko'zdan kechiradi. Shu paytda u barcha var nomlarini ro'yxatga oladi va ularga undefined qiymat beradi. Haqiqiy qiymat ("osh") esa faqat kod o'sha qatorga yetganda beriladi.

Ya'ni JavaScript yuqoridagi kodni amalda shunday ko'radi:

js
var taom;            // ro'yxatga olindi, qiymati undefined
console.log(taom);   // undefined
taom = "osh";        // endi qiymat berildi
console.log(taom);   // osh

Bu hodisa hoisting ("ko'tarish") deb ataladi — e'lon go'yo fayl tepasiga "ko'tarilgandek" bo'ladi. Faqat e'lon ko'tariladi, qiymat esa o'z joyida qoladi.

Hayotdan o'xshatish: maktab jurnali. O'quv yili boshida o'qituvchi jurnalga hamma o'quvchining ismini yozib qo'yadi. Lekin baho katakchalari hozircha bo'sh — baho faqat dars bo'lganda qo'yiladi. var ham shunday: nom oldindan "jurnalda" bor, qiymat esa keyinroq keladi.

4.2 Nega bu yomon?

undefined — xato emas, oddiy qiymat. Dastur to'xtamaydi va buzilgan natija bilan davom etadi:

js
console.log("Buyurtma:", taom, "— tayyor!");
var taom = "osh";

Konsolda:

text
Buyurtma: undefined — tayyor!

Mijoz ekranda "Buyurtma: undefined" ni ko'radi. let bo'lganda esa JavaScript darhol aytardi:

js
console.log("Buyurtma:", taom, "— tayyor!");
let taom = "osh";
text
ReferenceError: Cannot access 'taom' before initialization

Tarjimasi: "taom ga u tayyor bo'lishidan oldin murojaat qilib bo'lmaydi". Qizil xato yoqimsiz, lekin u xatoni aynan kerakli qatorda ko'rsatadi. var ning jim undefined i esa xatoni yashiradi.

Aslida let va const ham "ko'tariladi", lekin boshqacha — e'lon qatorigacha ularga tegib bo'lmaydi. Bu nozik farqni Hoisting va TDZ darslarida chuqur o'rganamiz. Hozir bitta qoida yetarli: avval e'lon qiling, keyin ishlating.

Tekshirib ko'ring: Nima chiqadi — undefined, 12800 yoki xato?

js
console.log(kurs);
var kurs = 12800;
Javob

undefined. var kurs e'loni fayl boshida ro'yxatga olingan, lekin 12800 qiymati faqat ikkinchi qatorda beriladi. var o'rniga let bo'lsa — ReferenceError: Cannot access 'kurs' before initialization.

5. 3-muammo: var blokni tanimaydi

Bu farqni tushunish uchun ikkita yangi tushuncha kerak: blok va ko'rinish doirasi.

5.1 Blok va ko'rinish doirasi

Blok (block) — jingalak qavslar { } ichidagi kod. Keyingi darslarda if va for bilan ishlaganda bloklar har qadamda uchraydi. Hozircha oddiy blokni ko'ramiz — JavaScript'da { } ni shunchaki yozsa ham bo'ladi.

Ko'rinish doirasi (scope) — o'zgaruvchi "ko'rinadigan", ya'ni ishlatilishi mumkin bo'lgan kod qismi. Bundan keyin uni qisqa qilib scope deymiz.

let va const ning scope'i — o'zi turgan blok. Blok ichida tug'iladi va blokdan chiqmaydi:

js
{
  let chegirma = 5000;
  console.log(chegirma);
}
console.log(chegirma);

Konsolda avval 5000 chiqadi, keyin qizil xato:

text
ReferenceError: chegirma is not defined

Hayotdan o'xshatish: blok — alohida xona. let bilan yaratilgan narsa xonada qoladi, eshikdan tashqariga chiqmaydi.

5.2 var blokdan "sizib chiqadi"

Endi xuddi shu kodni var bilan yozamiz:

js
{
  var chegirma = 5000;
  console.log(chegirma); // 5000
}
console.log(chegirma); // 5000

Xato yo'q! var bilan yaratilgan chegirma blokdan tashqarida ham yashayapti. var uchun { } devorlari go'yo yo'qdek — u ulardan bemalol o'tib ketadi.

Bu nega xavfli? Blok ichida vaqtincha kerak bo'lgan o'zgaruvchi tashqaridagi bir xil nomli o'zgaruvchini buzib qo'yishi mumkin:

js
var narx = 20000;

{
  var narx = 15000; // blok ichida vaqtincha chegirmali narx
}

console.log(narx); // 15000

Dasturchi blok ichida alohida narx yaratdim deb o'yladi. Aslida esa tashqaridagi narx o'zgarib ketdi. Asl narx 20000 yo'qoldi.

let bilan esa ichki va tashqi narx — ikki alohida o'zgaruvchi:

js
let narx = 20000;

{
  let narx = 15000; // faqat shu blok ichida
}

console.log(narx); // 20000

5.3 var faqat funksiyani taniydi

var ham chegarasiz emas. U taniydigan yagona devor — funksiya.

Funksiyani hali o'rganmadik, uni Funksiya e'lon qilish va chaqirish darsida to'liq ko'ramiz. Hozir bitta gap yetarli: funksiya — nom berilgan kod bo'lagi. function nomi() { ... } ichidagi kod nomi() deb chaqirilganda bajariladi.

js
function hisobla() {
  var soliq = 600000;
  console.log(soliq);
}

hisobla(); // funksiya ichidagi kodni ishga tushiradi
console.log(soliq);

Konsolda avval 600000, keyin:

text
ReferenceError: soliq is not defined

Funksiya ichidagi var tashqariga chiqmadi. Shuning uchun var ning scope'i funksiya scope (function scope) deyiladi. let va const niki esa — blok scope (block scope).

Oddiy { } blok Funksiya
let, const Ichida qoladi Ichida qoladi
var Tashqariga chiqadi Ichida qoladi

Bu mavzuni Scope asoslari darsida if, for va funksiyalar bilan chuqurroq ko'ramiz. U yerda eski kodda eng ko'p uchraydigan holat ham bor: for (var i = 0; ...) siklidagi i sikl tugagandan keyin ham yashab qoladi.

Tekshirib ko'ring: Konsolda nima chiqadi?

js
var ball = 10;
{
  var ball = 99;
}
console.log(ball);

var o'rniga ikkala joyda let bo'lsa-chi?

Javob

var bilan — 99. var blokni tanimaydi, shuning uchun ichkaridagi var ball — aslida o'sha tashqi ball, u qayta e'lon qilinib, 99 bo'ldi. let bilan — 10. Blok ichidagi let ball — alohida, faqat blokda yashaydigan o'zgaruvchi. Tashqi ball ga tegilmaydi.

6. 4-muammo: var global obyektga yoziladi

Bu xususiyat faqat brauzerda, oddiy <script> tegida ko'rinadi.

6.1 Global obyekt nima?

Brauzerda butun sahifa uchun bitta katta "umumiy obyekt" bor — window. Obyekt — bir nechta nomli qiymatni saqlaydigan "quti" (uni Obyektlar darsida o'rganamiz). window ichida brauzerning tayyor narsalari turadi: masalan, console ham aslida window.console. Uni brauzerning katta umumiy qutisi deb tasavvur qiling: console, alert kabi hamma tayyor asboblar shu qutida turadi. window.console — "window qutisidagi console" degani, nuqta "ichidagi" ma'nosini beradi.

Bunday obyekt global obyekt deyiladi. Uning universal nomi — globalThis. Brauzerda globalThis — bu window, Node'da esa global degan obyekt.

6.2 var o'z nomini global obyektga yozadi

Fayl eng tashqi qismida (hech qanday funksiya ichida emas) var bilan e'lon qilingan o'zgaruvchi window ning xususiyatiga aylanadi. let va const esa yo'q:

js
var shahar = "Toshkent";
let viloyat = "Toshkent viloyati";

console.log(window.shahar); // Toshkent
console.log(window.viloyat); // undefined
console.log(globalThis.shahar); // Toshkent

var shahar — window ichiga yozildi. let viloyat esa oddiy o'zgaruvchi bo'lib qoldi, window ga tegmadi.

6.3 Bu qanday muammo keltirib chiqaradi?

window ichida brauzerning yuzlab o'z nomlari bor. var bilan tasodifan ulardan birini tanlasangiz — brauzerning narsasini buzasiz.

Mana haqiqiy misol. window da name degan maxsus xususiyat bor va u har qanday qiymatni matnga aylantiradi:

js
var name = 2026;
console.log(name + 1); // 20261

Kutilgan 2027 o'rniga 20261 chiqdi! var name brauzerning window.name iga yozildi va son "2026" matniga aylandi. Matnga + 1 qo'shilsa, qo'shish emas, yopishtirish bo'ladi: "2026" va 1 → "20261".

let name = 2026; yozilganda esa name + 1 to'g'ri 2027 beradi — let window ga tegmaydi.

Ikkinchi muammo — nomlar to'qnashuvi. Sahifaga 5 ta turli skript ulangan bo'lsa, hammasining var lari bitta umumiy window ga tushadi. Bir skriptdagi var narx boshqa skriptdagi var narx ni bosib ketadi.

Maslahat: Node'da (node fayl.js) va zamonaviy modul fayllarda (<script type="module">) bu muammo yo'q: har bir fayl o'z "xonasi"ga ega, var global obyektga yozilmaydi. Global obyekt haqida batafsil — Global obyekt va globalThis darsida.

Tekshirib ko'ring: Brauzerdagi oddiy <script> da var mavzu = "qorong'i"; va const til = "uz"; yozildi. window.mavzu va window.til nima bo'ladi?

Javob

window.mavzu — "qorong'i", chunki tashqi var global obyektga yoziladi. window.til — undefined, chunki const (xuddi let kabi) window ga yozilmaydi.

7. To'rt muammo bitta jadvalda

Xususiyat var let / const
Qayta e'lon qilish Mumkin, jim SyntaxError
E'londan oldin ishlatish undefined ReferenceError
Scope Funksiya Blok
Brauzerda window ga yozilish Ha Yo'q

E'tibor bering: har bir qatorda let/const yoki xato beradi, yoki o'z joyida qoladi. var esa jim qoladi yoki tarqalib ketadi. Yaxshi til xatoni erta va baland ovozda aytadi — let va const shunday qilish uchun yaratilgan.

8. Eski kodni o'qish va yangilash

8.1 Eski kodni o'qish

Eski kodda var ni ko'rganda o'zingizga ikki savol bering:

  1. Bu o'zgaruvchi keyin qayta tayinlanadimi? Bu savol qaysi kalit so'zga almashtirishni ko'rsatadi.
  2. U blok ichidami? Bo'lsa, tashqarida ham ishlatilishi mumkin — var blokdan chiqadi.

Maslahat: Darslik yoki forum javobidagi kodda var ko'rsangiz — bu ko'pincha 2015-yilgacha yozilgan material ekanini bildiradi. Sanasini tekshiring: ichida boshqa eskirgan usullar ham bo'lishi mumkin.

8.2 var ni let yoki const ga almashtirish

Qoida oddiy: qiymat hech qachon qayta tayinlanmasa — const, tayinlansa — let.

Eski kod:

js
var dokon = "Chorsu";
var tushum = 0;
tushum = tushum + 120000;
tushum = tushum + 85000;
console.log(dokon, tushum); // Chorsu 205000

Yangilangan kod:

js
const dokon = "Chorsu";
let tushum = 0;
tushum = tushum + 120000;
tushum = tushum + 85000;
console.log(dokon, tushum); // Chorsu 205000

dokon qayta tayinlanmaydi — const. tushum o'zgaradi — let. Natija bir xil, lekin endi kod xavfsizroq.

Diqqat: Almashtirgandan keyin kodni albatta ishga tushirib ko'ring. Eski kod var ning g'alati xususiyatiga — e'londan oldin ishlatishga yoki blokdan chiqishga — tayangan bo'lishi mumkin. Unda let bilan xato chiqadi. Bu yaxshi: xato yashirin muammoni ko'rsatdi. Endi uni to'g'ri tuzatasiz.

9. Ko'p uchraydigan xatolar

9.1 var va let ni bir nom bilan aralashtirish

Eski kodga yangi qator qo'shganda shunday bo'ladi:

js
var mijoz = "Ali";
let mijoz = "Vali";
text
SyntaxError: Identifier 'mijoz' has already been declared

var o'zi qayta e'lon qilishga ruxsat beradi, lekin let bilan aralashganda — yo'q. Yechim: ikkinchi let ni olib tashlab, oddiy tayinlash qiling (mijoz = "Vali";) yoki yangi nom bering.

9.2 Almashtirilgandan keyin "yo'qolgan" o'zgaruvchi

js
{
  let ogohlantirish = "Kam qoldi!";
}
console.log(ogohlantirish);
text
ReferenceError: ogohlantirish is not defined

Bu kod var bilan ishlagan edi — o'zgaruvchi blokdan sizib chiqardi. let ga almashtirilgach, u blokda qoldi. Yechim: o'zgaruvchini blokdan oldin e'lon qiling, blok ichida esa faqat qiymat bering:

js
let ogohlantirish = "";
{
  ogohlantirish = "Kam qoldi!";
}
console.log(ogohlantirish); // Kam qoldi!

9.3 Darslikdan ko'chirib var yozish

Eski darslik yoki video var bilan yozilgan bo'lsa, ko'pchilik ham var yozib ketaveradi. Kod ishlaydi — lekin siz yuqoridagi to'rt tuzoqni o'z loyihangizga olib kirasiz. Ko'chirayotganda var ni darhol const yoki let ga almashtiring.

10. Mashqlar

1-mashq (oson): Natijani oldindan ayting

Kodni ishga tushirmasdan, konsolda nima chiqishini yozing. Keyin tekshiring.

js
console.log(yil);
var yil = 2026;
var yil = 2027;
console.log(yil);
Yechim

Konsolda:

text
undefined
2027

Birinchi qatorda yil allaqachon ro'yxatga olingan (hoisting), lekin qiymati hali undefined. Keyin var yil ikki marta e'lon qilindi — xato yo'q, oxirgi qiymat 2027 qoldi.

2-mashq (o'rta): var ni almashtiring

Bu kodni var siz qayta yozing. Har o'zgaruvchi uchun to'g'ri kalit so'zni tanlang: qayta tayinlanmasa — const, tayinlansa — let.

js
var mahsulot = "Non";
var narx = 4000;
var soni = 3;
soni = soni + 2;
console.log(mahsulot, narx * soni); // Non 20000
Yechim
js
const mahsulot = "Non";
const narx = 4000;
let soni = 3;
soni = soni + 2;
console.log(mahsulot, narx * soni); // Non 20000

mahsulot va narx qayta tayinlanmaydi — const. soni esa soni = soni + 2 qatorida o'zgaradi — let.

3-mashq (qiyin): Eski kodning yashirin xatosi

Bu eski kod ishlaydi, lekin noto'g'ri natija beradi. Asl narx 20000 so'm edi.

js
var narx = 20000;
{
  var narx = narx - 5000;
  console.log("Chegirmali:", narx); // Chegirmali: 15000
}
console.log("Asl narx:", narx); // Asl narx: 15000
  1. Nega "Asl narx" ham 15000 bo'lib chiqdi?
  2. Kodni let/const bilan shunday qayta yozingki, Chegirmali: 15000 va Asl narx: 20000 chiqsin.

Ishora: ichki qiymatga alohida nom bering, masalan chegirmaliNarx.

Yechim
  1. var blokni tanimaydi. Blok ichidagi var narx — yangi o'zgaruvchi emas, o'sha tashqi narx ning o'zi. U qayta e'lon qilinib, 15000 ga aylandi va asl narx yo'qoldi.

  2. Tuzatilgan kod:

js
const narx = 20000;
{
  const chegirmaliNarx = narx - 5000;
  console.log("Chegirmali:", chegirmaliNarx);
}
console.log("Asl narx:", narx);

Konsolda:

text
Chegirmali: 15000
Asl narx: 20000

Endi ikkala qiymat alohida. narx — const, uni tasodifan o'zgartirib bo'lmaydi. chegirmaliNarx esa faqat blok ichida yashaydi.

Nega ichkarida ham narx nomini let bilan ishlatmadik? let narx = narx - 5000 yozsangiz, blok ichida yangi narx paydo bo'ladi. JavaScript narx so'zini ko'rganda avval shu blokdagi narx ni qidiradi — tashqaridagisiga qaramaydi. Ichki narx esa hali qiymat olmagan. Natija: ReferenceError: Cannot access 'narx' before initialization ("narx ga qiymat berilishidan oldin murojaat qilib bo'lmaydi"). Bu nozik holatni TDZ darsida ko'ramiz. Hozircha qoida: ichki qiymatga alohida, ma'noli nom bering.

11. Real ishda

  • Eski loyihalar (legacy code): ko'p kompaniyalarda 5–10 yillik kod bor. Yangi dasturchiga ko'pincha "shu faylni zamonaviylashtir" degan vazifa beriladi — var ni let/const ga o'tkazish shulardan biri.
  • ESLint loyihalarda no-var qoidasi bilan ishlaydi: var yozsangiz, darhol ogohlantiradi va ko'p holatda o'zi let/const ga almashtirib beradi. Uni ESLint va Prettier darsida sozlaymiz.
  • Intervyu: "var, let va const ning farqi nima?" — boshlang'ich dasturchiga eng ko'p beriladigan savollardan biri. Endi to'liq javob bera olasiz: scope, qayta e'lon, hoisting va global obyekt.
  • Kutubxona ichida: eski brauzerlar uchun tayyorlangan ba'zi kutubxona fayllarida hali ham var ko'rasiz. Ularni vositalar avtomatik yaratadi — bu siz yozadigan kod uchun namuna emas.

Xulosa

  • var — 2015-yilgacha yagona usul edi; hozir faqat eski kodda uchraydi. Yangi kodda yozmang.
  • var qayta e'lon qilishga jimgina ruxsat beradi — let/const esa SyntaxError beradi.
  • var e'londan oldin undefined beradi (hoisting) — let/const esa ReferenceError.
  • var — funksiya scope: { } blokidan chiqib ketadi, funksiyadan esa chiqmaydi.
  • Brauzerdagi oddiy <script> da tashqi var window (globalThis) ga yoziladi va brauzer nomlarini buzishi mumkin.
  • Eski kodni yangilash: qayta tayinlanmasa — const, tayinlansa — let, keyin albatta ishga tushirib tekshiring.

Keyingi dars: Ma'lumot turlari xaritasi: primitivlar va obyektlar — o'zgaruvchida qanday qiymatlar saqlanishi mumkinligini va ular qanday turlarga bo'linishini ko'ramiz.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript var: nega undan voz kechildi va eski kodda uni qanday o'qish kerak — IlmHamroh