Hoisting — o'zgaruvchi va funksiyalar qanday ko'tariladi

~15 daq · JavaScript · Funksiyalar chuqurroq

Muammodan boshlaylik

console.log(ism); // undefined — xato emas!
var ism = "Ali";

salomlash(); // "Salom!" — e'lon qilinishidan oldin ishlaydi!
function salomlash() {
  console.log("Salom!");
}

Bu qanday ishlaydi? ism e'lon qilinishidan oldin ishlatildi — lekin xato chiqmadi. salomlash e'lon qilinishidan oldin chaqirildi — ishladi. Bu — hoisting.


Hoisting nima?

JavaScript kodni ishga tushirishdan oldin bir marta "skanerlaydi" — barcha e'lonlarni topib, xotiraga oladi. Sanki ular faylning tepasiga "ko'tarilgandek" ishlaydi.

Hayotiy o'xshatma: imtihon oldidan o'qituvchi savollar ro'yxatini tuzadi — hali imtihon boshlanmagan, lekin savollar allaqachon ma'lum. Hoisting ham shunday — kod bajarilishidan oldin e'lonlar "ma'lum" bo'ladi.


Function Declaration — to'liq ko'tariladi

Function declaration — nom va tanasi bilan birga ko'tariladi. Shu sababli e'lon qilinishidan oldin chaqirish mumkin:

natija(); // ✅ "Ishladi!" — hoisting tufayli

function natija() {
  console.log("Ishladi!");
}

JavaScript buni quyidagicha ko'radi:

// JavaScript ichida shunday ishlaydi:
function natija() { console.log("Ishladi!"); } // ← tepaga ko'tarildi
natija(); // ✅

var — e'lon ko'tariladi, qiymat ko'tarilmaydi

var bilan e'lon qilingan o'zgaruvchi — e'loni ko'tariladi, lekin qiymati ko'tarilmaydi. Qiymat tayinlanmaguncha undefined bo'ladi.

console.log(ism); // undefined — xato emas, lekin qiymat yo'q
var ism = "Ali";
console.log(ism); // "Ali"

JavaScript buni quyidagicha ko'radi:

var ism;           // ← e'lon tepaga ko'tarildi
console.log(ism);  // undefined
ism = "Ali";       // ← qiymat o'z joyida qoldi
console.log(ism);  // "Ali"

let va const — Temporal Dead Zone

let va const ham texnik jihatdan ko'tariladi — lekin Temporal Dead Zone (TDZ) tufayli e'lon qilinishidan oldin ishlatib bo'lmaydi.

console.log(ism); // ❌ ReferenceError: Cannot access 'ism' before initialization
let ism = "Ali";

TDZ — o'zgaruvchi e'lon qilingan qatordan oldingi hudud. Bu hududda o'zgaruvchi mavjud, lekin qiymat yo'q — murojaat qilish xato.

Nima uchun TDZ yaxshi?

var ning undefined qaytarishi — yashirin xato. Siz o'zgaruvchi yo'q deb o'ylaysiz, lekin undefined keladi — xatoni topish qiyinlashadi. let/const esa darhol xato beradi — muammo aniq ko'rinadi.

// var — yashirin muammo
console.log(narx); // undefined — xato yo'q, lekin noto'g'ri
var narx = 100;

// let — aniq xato
console.log(narx); // ❌ ReferenceError — darhol bilinadi
let narx = 100;

Function Expression va Arrow Function — ko'tarilmaydi

Function expression va arrow function — o'zgaruvchiga tayinlanadi. O'zgaruvchi qoidalari ishlaydi:

salomlash(); // ❌ ReferenceError (let/const) yoki TypeError (var)

const salomlash = () => {
  console.log("Salom!");
};

var bilan bo'lsa:

salomlash(); // ❌ TypeError: salomlash is not a function
// (var ko'tarildi, lekin qiymati undefined — funksiya emas)

var salomlash = function() {
  console.log("Salom!");
};

Amalda hoisting qoidalari

Function Declaration — istalgan joydan chaqirish mumkin

// ✅ Bu ishlaydi — declaration hoisting
const natija = hisoblash(5, 3);

function hisoblash(a, b) {
  return a + b;
}

Lekin bu yaxshi amaliyot emas — funksiyani ishlatishdan oldin e'lon qilish kodni o'qishni osonlashtiradi.

let/const — har doim e'londan keyin ishlatiladi

// ✅ To'g'ri tartib
const ism = "Ali";
console.log(ism);

// ❌ Noto'g'ri
console.log(ism);
const ism = "Ali";

Tez-tez uchraydigan xatolar

var hoisting tufayli kutilmagan undefined:

function ko'rsat() {
  console.log(x); // undefined — xato emas, lekin noto'g'ri
  if (true) {
    var x = 5;
  }
}
// var funksiya scope — if bloki ichida bo'lsa ham tepaga ko'tariladi

Funksiyani e'lon qilinishidan oldin chaqirish — yashirin bog'liqlik:

// Ishlaydi, lekin o'qish qiyin — qayerda e'lon qilingan?
const natija = hisoblash(10);
// ... 200 qator kod ...
function hisoblash(x) { return x * 2; }

Bir xil nomli function declaration — oxirgisi g'alaba qiladi:

function salomlash() { return "Salom!"; }
function salomlash() { return "Hi!"; }

salomlash(); // "Hi!" — ikkinchisi birinchisini ustiga yozdi

Xulosa

Function Declaration — to'liq ko'tariladi. E'lon qilinishidan oldin chaqirish mumkin.

var — e'loni ko'tariladi, qiymati undefined. Ishlatilmaydi.

let va const — TDZ tufayli e'lon qilinishidan oldin ishlatib bo'lmaydi. Xato aniq ko'rinadi.

Function Expression va Arrow — o'zgaruvchi qoidalari ishlaydi. Ko'tarilmaydi.

Amalda: let/const ishlatiladi, funksiyalar ishlatilishidan oldin e'lon qilinadi.


Keyingi dars

11-dars: Closure — nima va qanday ishlaydi