Asoslar (JavaScript)
JavaScriptning eng ko'p so'raladigan asoslari: o'zgaruvchilar e'lon qilish, funksiyalar, closure, zamonaviy sintaksis va massiv/ob'ekt metodlari.
var / let / const — scope, hoisting, TDZ
Nima bu?
`var`, `let` va `const` — o'zgaruvchi e'lon qilish usullari. `var` funksiya scope'ida ishlaydi va hoisting bilan `undefined` bo'lib ko'tariladi. `let` va `const` block scope'ga ega; e'lon qilinmasdan oldin ishlatilsa **Temporal Dead Zone (TDZ)** xatosi beradi. `const` reference'ni o'zgartirmaydi, lekin ob'ekt ichidagi property'larni o'zgartirish mumkin.Kod misoli
console.log(a); // undefined (var hoisting)
var a = 1;
// console.log(b); // ReferenceError — TDZ
let b = 2;
function test() {
if (true) {
var x = 10; // butun funksiyaga ta'sir qiladi
let y = 20; // faqat if bloki ichida
}
console.log(x); // 10
// console.log(y); // ReferenceError
}
const user = { name: 'Ali' };
user.name = 'Vali'; // OK — ob'ekt ichini o'zgartirish
// user = {}; // TypeError — reference o'zgarmaydi
Imtihonda
- `var` va `let` o'rtasidagi farq nima? Block scope va TDZ haqida tushuntiring. - Loop ichida `var` bilan `setTimeout` ishlatilsa nima bo'ladi? (`let` bilan solishtiring)Yodlash uchun
Default: `const` ishlat, qayta tayinlash kerak bo'lsa `let`, `var` dan qoch.Arrow vs Regular function — this farqi
Nima bu?
Oddiy funksiyada `this` chaqiruv kontekstiga bog'liq (kim chaqirsa, shu ob'ekt). Arrow funksiyada `this` lexical — ya'ni yozilgan joydagi `this` ni meros qilib oladi va `call`/`apply`/`bind` bilan o'zgartirilmaydi. Arrow funksiyalar `arguments` ob'ektiga ham ega emas va constructor sifatida ishlatilmaydi.Kod misoli
const obj = {
name: 'Angular',
regular() {
setTimeout(function () {
console.log(this.name); // undefined — this = window/global
}, 0);
},
arrow() {
setTimeout(() => {
console.log(this.name); // 'Angular' — lexical this
}, 0);
},
};
obj.regular();
obj.arrow();
// Arrow constructor bo'lmaydi:
// const Person = (name) => { this.name = name; }; // TypeError
Imtihonda
- Nima uchun Angular component metodlarida arrow funksiya tavsiya etilmaydi? (har render'da yangi reference) - `this` ni saqlab qolish uchun arrow o'rniga nima ishlatish mumkin?Yodlash uchun
`this` kontekst kerak bo'lsa — oddiy funksiya; lexical `this` kerak bo'lsa — arrow.Closure — yopilish va lexical scope
Nima bu?
Closure — funksiya o'z yaratilgan lexical scope'dagi o'zgaruvchilarni eslab qoladi, hatto tashqi funksiya tugaganidan keyin ham. Bu private state, factory pattern va callback'larda keng qo'llaniladi. Har bir inner funksiya tashqi scope'ning "yopilgan" nusxasiga ega bo'ladi.Kod misoli
function createCounter(initial = 0) {
let count = initial; // private — tashqaridan to'g'ridan ko'rinmaydi
return {
increment() { count += 1; return count; },
decrement() { count -= 1; return count; },
getCount() { return count; },
};
}
const counter = createCounter(5);
counter.increment(); // 6
counter.increment(); // 7
// counter.count — undefined (closure orqali himoyalangan)
// Loop + closure klassik muammo:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 3, 3, 3
}
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 200); // 0, 1, 2
}
Imtihonda
- Closure nima? Amaliy misol bering (masalan, debounce yoki counter). - Closure xotira leak keltirishi mumkinmi? Qachon?Yodlash uchun
Funksiya + uning tashqi scope'dagi o'zgaruvchilar = closure.Destructuring, Spread, Rest operator
Nima bu?
Destructuring — massiv yoki ob'ektdan qiymatlarni ajratib olish. Spread (`...`) iteratsiya qilinadigan yoki ob'ekt property'larini "yoyish" uchun ishlatiladi (nusxa olish, birlashtirish). Rest (`...`) qolgan argument yoki elementlarni bitta massiv/ob'ektga yig'adi. Uchala operator kodni qisqa va o'qilishi oson qiladi.Kod misoli
// Destructuring
const [first, , third] = [1, 2, 3];
const { name, age, city = 'Toshkent' } = { name: 'Ali', age: 25 };
// Spread — nusxa va birlashtirish
const defaults = { theme: 'light', lang: 'uz' };
const userPrefs = { ...defaults, theme: 'dark' }; // theme ustidan yoziladi
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4]; // [1, 2, 3, 4]
// Rest — qolganini yig'ish
function sum(first, ...rest) {
return rest.reduce((acc, n) => acc + n, first);
}
sum(10, 1, 2, 3); // 16
const { id, ...productWithoutId } = { id: 1, title: 'Kitob', price: 50000 };
// productWithoutId = { title: 'Kitob', price: 50000 }
Imtihonda
- Shallow copy va spread farqi nima? Nested ob'ektda nima bo'ladi? - Rest parametr va `arguments` ob'ekti farqi?Yodlash uchun
Spread — yoyish; Rest — qolganini yig'ish (destructuring yoki parametrda).Optional chaining (?.) va Nullish coalescing (??)
Nima bu?
Optional chaining (`?.`) — `null` yoki `undefined` bo'lganda xato bermasdan `undefined` qaytaradi (property, metod, massiv indeks uchun). Nullish coalescing (`??`) — faqat `null` yoki `undefined` bo'lsa o'ng tomondagi default qiymatni oladi. `||` dan farqi: `??` `0`, `''`, `false` kabi "falsy" lekin valid qiymatlarni saqlab qoladi.Kod misoli
const user = {
profile: {
address: { city: 'Samarqand' },
},
};
console.log(user?.profile?.address?.city); // 'Samarqand'
console.log(user?.phone?.number); // undefined (xato emas)
const callback = user?.onSave?.(); // metod bo'lmasa undefined
// ?? vs ||
const count = 0;
console.log(count || 10); // 10 — 0 falsy deb hisoblandi
console.log(count ?? 10); // 0 — faqat null/undefined uchun default
const title = null;
const display = title ?? 'Sarlavhasiz'; // 'Sarlavhasiz'
Imtihonda
- `?.` va `&&` zanjir farqi nima? - `??` va `||` qachon ishlatiladi? (`0` yoki bo'sh string misoli)Yodlash uchun
Xavfsiz kirish — `?.`; faqat null/undefined uchun default — `??`.Array metodlari — map, filter, reduce, find, some, every, flat
Nima bu?
Massiv metodlari immutable yoki mutable usulda ma'lumot bilan ishlash imkonini beradi. `map` — transform, `filter` — tanlash, `reduce` — yig'indiga keltirish, `find`/`findIndex` — birinchi mos element, `some`/`every` — shart tekshiruvi, `flat` — ichma-ich massivni tekislash. Intervyuda murakkab transformlarni `reduce` bilan yozish ko'p so'raladi.Muhim gotcha: map, filter, flat yangi massiv qaytaradi (asl massiv o'zgarmaydi), lekin sort, reverse, splice asl massivni mutatsiya qiladi — Angular'da OnPush yoki NgRx state bilan ishlaganda bu farqni bilmaslik reference tenglik xatolariga olib keladi. Shuningdek, reduce ga initial qiymat berilmasa, bo'sh massivda TypeError beradi va birinchi element accumulator sifatida ishlatiladi — bu ko'pincha noto'g'ri natija beradi.
Kod misoli
const products = [
{ id: 1, name: 'Telefon', price: 5000000, category: 'elektronika' },
{ id: 2, name: 'Kitob', price: 45000, category: 'kitob' },
{ id: 3, name: 'Noutbuk', price: 12000000, category: 'elektronika' },
];
const names = products.map((p) => p.name);
// ['Telefon', 'Kitob', 'Noutbuk']
const expensive = products.filter((p) => p.price > 100000);
// Noutbuk
const total = products.reduce((sum, p) => sum + p.price, 0);
// 17045000
const laptop = products.find((p) => p.name === 'Noutbuk');
const hasBook = products.some((p) => p.category === 'kitob'); // true
const allPositive = products.every((p) => p.price > 0); // true
const nested = [1, [2, [3, 4]]];
nested.flat(2); // [1, 2, 3, 4]
Imtihonda
- `map` va `forEach` farqi nima? - `reduce` yordamida massivdagi ob'ektlarni `{ id: item }` ko'rinishidagi Map ga aylantiring.Yodlash uchun
Yangi massiv — `map`/`filter`; bitta qiymat — `reduce`/`find`; shart — `some`/`every`.Object metodlari — keys, values, entries, assign
Nima bu?
`Object.keys`, `Object.values`, `Object.entries` ob'ekt ustida iteratsiya qilish uchun ishlatiladi. `Object.assign` bir nechta manba ob'ekt property'larini target'ga nusxalaydi (shallow). Zamonaviy alternativ — spread operator. `Object.fromEntries` entries massivini ob'ektga aylantiradi — `Map` bilan ishlashda foydali.Gotcha: assign va spread ikkalasi ham faqat birinchi darajali property'larni nusxalaydi — ichma-ich (nested) ob'ekt hali ham eski reference'ga ishora qiladi, shu sababli nested obyektni o'zgartirsangiz asl ob'ekt ham o'zgaradi:
const original = { user: { name: 'Ali' } };
const copy = { ...original };
copy.user.name = 'Vali';
console.log(original.user.name); // 'Vali' — nested ob'ekt umumiy reference
Chuqur nusxa kerak bo'lsa structuredClone(obj) yoki JSON.parse(JSON.stringify(obj)) (funksiya/undefined/Date yo'qotadi) ishlatiladi.
Kod misoli
const config = { apiUrl: '/api', timeout: 5000, retry: 3 };
Object.keys(config); // ['apiUrl', 'timeout', 'retry']
Object.values(config); // ['/api', 5000, 3]
Object.entries(config); // [['apiUrl', '/api'], ['timeout', 5000], ...]
const updated = Object.assign({}, config, { timeout: 8000, debug: true });
// yoki: const updated = { ...config, timeout: 8000, debug: true };
// entries → ob'ekt (masalan, Map dan)
const map = new Map([['a', 1], ['b', 2]]);
const obj = Object.fromEntries(map); // { a: 1, b: 2 }
// Iteratsiya
for (const [key, value] of Object.entries(config)) {
console.log(`${key}: ${value}`);
}
Imtihonda
- `Object.assign` va spread farqi bormi? (Shallow copy ikkalasida ham) - Ob'ekt property'larini o'zgartirmasdan yangi ob'ekt qanday yaratiladi?Yodlash uchun
Iteratsiya — `entries`; nusxa/birlashtirish — spread yoki `assign`.