JavaScript bo'yicha eng muhim 80 ta coding intervyu savoli va javoblari
Har qanday tajriba darajasi uchun juda mos bo'lgan ushbu eng muhim 80 ta JavaScript coding intervyu savoli va javoblari yordamida navbatdagi intervyuingizga puxta tayyorlaning.
Muallif: Fernando Doglio
Xuddi uning ekotizimi kabi, JavaScript coding intervyu savollari olami ham doimiy ravishda o'zgarib, rivojlanib boradi. Ajoyib dasturlash tili bo'lgani uchun JavaScript dinamik veb-sahifalardan tortib murakkab veb-serverlargacha bo'lgan hamma narsani yaratishda ishlatiladi.
Agar siz JavaScript developer lavozimini izlayotgan bo'lsangiz, tilni puxta bilib olganingizdan so'ng (bunga kirishish uchun JavaScript roadmap'imiz ajoyib boshlang'ich nuqta) bunday intervyularga tayyor bo'lish muvaffaqiyatingiz uchun hal qiluvchi ahamiyatga ega. Agar siz hiring manager bo'lsangiz, yaxshi savollar to'plamiga ega bo'lish ham xuddi shunchalik muhim.
Ushbu maqolada dasturchining JavaScript'dagi amaliy ko'nikmalarini sinash uchun mo'ljallangan savollarning juda batafsil ro'yxatini topasiz.
Intervyuga tayyorgarlik
Savollarga sho'ng'ishdan oldin intervyu oluvchilar nimani izlayotganini tushunib olish muhim.
Ular sizning muammolarni qanday hal qilishingizni, noma'lum narsaga qanday yondashishingizni va yechimlaringiz ortidagi fikrlash jarayonini ko'rishni xohlashadi.
Ular sizning ma'lumotlar tuzilmalari haqida qanday fikrlashingizni va real hayotiy vaziyatlarga qanday yondashishingizni tushunishni istashadi. Bu nazariy vositalarni haqiqiy muammolarni hal qilishda qanday qo'llaysiz?
Bundan tashqari, JavaScript'ning asosiy tushunchalarini takrorlab chiqishni va toza, samarali kod yozishni mashq qilishni unutmang. Oxir-oqibat, siz har kuni aynan shu ish bilan shug'ullanasiz.
Siz const keyword'idan tortib callback funksiya qanday ishlashigacha bo'lgan hamma narsani bemalol bilishingiz kerak. Esda tuting: yechimlarni shunchaki yodlab olmang; asosiy tamoyillarni tushuning.
Flashcard'lar bilan o'zingizni sinab ko'ring
Siz ushbu flashcard'lardan foydalanishingiz yoki savollarni ro'yxat ko'rinishida ko'rish uchun quyidagi savollar ro'yxati bo'limiga o'tishingiz mumkin.
Savollar ro'yxati
Agar savollarni ro'yxat ko'rinishida ko'rishni afzal ko'rsangiz, ularni quyida topishingiz mumkin.
Boshlang'ich darajadagi savollar
var, let va const o'rtasida qanday farq bor?
var global scope yoki function scope'ga ega; let va const esa block scope'ga ega.
var bilan e'lon qilingan o'zgaruvchini qayta e'lon qilish ham, yangilash ham mumkin, let bilan e'lon qilinganini esa yangilash mumkin, lekin qayta e'lon qilib bo'lmaydi.
Va nihoyat, const'ni qayta e'lon qilib ham, yangilab ham bo'lmaydi — shuning uchun ular “konstantalar” deb ataladi.
Kiruvchi massivdagi barcha elementlar yig'indisini qaytaradigan sumArray(arr) funksiyasini yozing.
Buning uchun reduce metodidan foydalanishingiz mumkin:
function sumArray(arr) {
return arr.reduce((acc, current) => acc + current, 0);
}
Bu metod “accumulator” funksiyasini massivning har bir elementiga qo'llaydi: u birinchi parametr sifatida joriy to'plangan qiymatni (funksiyaning oldingi chaqiruvi natijasini), ikkinchi parametr sifatida esa ayni paytda qayta ishlanayotgan qiymatni oladi. Yuqoridagi koddagi “0” shunchaki accumulator o'zgaruvchisining boshlang'ich qiymatini belgilaydi.
Berilgan string palindrom ekanini qanday tekshirasiz? Buni ko'rsatish uchun isPalindrome funksiyasini yozing.
Oddiy isPalindrome funksiyasi berilgan string'ni olib, uni teskari aylantirishi va asl string bilan solishtirishi mumkin.
function isPalindrome(str) {
return str === str.split('').reverse().join('');
}
JavaScript'da string'ni to'g'ridan-to'g'ri teskari aylantirishning usuli yo'qligi sababli, biz string'ni belgilar massiviga aylantirib, o'sha massivni teskari aylantiryapmiz. So'ngra asl kiruvchi qiymat bilan solishtirish uchun bu qiymatlarning barchasini bitta string'ga birlashtiramiz.
JavaScript'dagi type coercion'ni tushuntiring. Misol keltiring.
Type coercion — JavaScript'ning qiymatlarni bir data type'dan boshqasiga avtomatik ravishda o'zgartirishi.
Masalan, '5' + 5 natijasi '55' bo'ladi, chunki son va string'ni qo'shishga urinilganda 5 soni string'ga coerce qilinadi.
Berilgan string'ni teskari aylantiradigan funksiya yozing. Oddiy reversestring funksiyasi kifoya qiladi.
Oddiy reversestring funksiyasini quyidagicha yozishingiz mumkin:
function reversestring(str) {
return str.split('').reverse().join('');
}
Avval string'ni belgilar massiviga ajratasiz, uni teskari aylantirasiz, so'ng barcha belgilarni qaytadan birlashtirasiz. Hosil bo'lgan string asl string'ning teskari ko'rinishi bo'ladi.
Kiruvchi massivdagi istalgan ikki element orasidagi eng katta farqni qanday topasiz?
Bu masalani kiruvchi massiv bo'ylab iteration qilib, bir vaqtning o'zida maksimal va minimal qiymatlarni hisoblash orqali yechishingiz mumkin. Oxirida esa shu qiymatlar orasidagi farqni qaytarasiz.
Mana uni amalga oshirishga namuna:
function findMaxDifference(arr) {
// Check if the array has at least two elements.
if (arr.length < 2) {
return 0;
}
// Initialize both min and max values with the first element of the array.
let minVal = arr[0];
let maxVal = arr[0];
// Iterate through the array starting from the second element in a single pass.
for (let i = 1; i < arr.length; i++) {
// Check if the current element is smaller than the current minimum value.
if (arr[i] < minVal) {
minVal = arr[i];
} else if (arr[i] > maxVal) {
maxVal = arr[i]; }
}
// The result is the difference between the maximum and minimum values found.
return maxVal - minVal;
}
Berilgan son tub son ekanini tekshiradigan funksiya yozing. Funksiyangizni isprime deb nomlang.
isprime funksiyasi sonning 2 dan shu sonning kvadrat ildizigacha bo'lgan biror butun songa bo'linish-bo'linmasligini tekshiradi. Agar shunday son topilsa, funksiya false qaytarishi kerak. Mana bu funksiyani amalga oshirishning mumkin bo'lgan varianti:
function isprime(num) {
// Prime numbers are natural numbers greater than 1.
if (num <= 1) {
return false;
}
// 2 is the only even prime number.
if (num === 2) {
return true;
}
// If the number is even and greater than 2, it's not prime.
if (num % 2 === 0) {
return false;
}
// Check for divisibility from 3 up to the square root of the number.
// We can skip even numbers by incrementing by 2.
for (let i = 3; i <= Math.sqrt(num); i += 2) {
// If the number is divisible by i, it's not prime.
if (num % i === 0) {
return false;
}
}
// If no divisors are found, the number is prime.
return true;
}
Global scope'da var c = 10 berilgan bo'lsa, funksiya ichida var c = 20 e'lon qilsangiz nima bo'ladi?
Funksiya ichidagi var c = 20 lokal scope'ga ega bo'ladi, shuning uchun global scope'dagi o'zgaruvchi 10 bo'lib qolaveradi.
Data type object type ekanini qanday tekshirasiz?
Buning uchun typeof obj === 'object' && obj !== null dan foydalanishingiz mumkin.
null tekshiruvi muhim, chunki typeof null ham 'object' qaytaradi.
Recursive funksiya yordamida sonning faktorialini hisoblaydigan factorial(n) funksiyasini yozing.
Recursive funksiya — o'zini o'zi chaqiradigan funksiya. Shu tamoyilga amal qiladigan va sonning faktorialini hisoblaydigan funksiyani quyidagicha yozishimiz mumkin:
function factorial(n) {
if (n === 0) { return 1; }
return n * factorial(n - 1);
}
Massiv ichidagi barcha elementlar bo'ylab qanday iteration qilib, ularni yangi bo'sh massivga qo'shgan bo'lardingiz?
Buning uchun for loop'dan foydalanardingiz. Har bir elementni yangi bo'sh massivga qo'shish uchun esa newArray.push(element) dan foydalanardingiz.
null va undefined o'rtasidagi farqni tushuntiring.
Bu ikki atama ko'pincha bir-biri bilan adashtiriladi.
undefined o'zgaruvchi e'lon qilingan, lekin unga qiymat berilmaganini bildiradi. null esa qiymat yo'qligini yoki bo'sh string'ni aniq ko'rsatish uchun o'zgaruvchiga berilishi mumkin bo'lgan qiymat.
Massivdan falsy qiymatlarni olib tashlaydigan removeFalsyValues(arr) funksiyasini qanday yozgan bo'lardingiz?
Falsy qiymatlar — coerce qilinganda “false” deb baholanadigan qiymatlar, masalan, 0 yoki bo'sh massiv.
removeFalsyValues funksiyasi filter metodidan foydalanadigan oddiy funksiya bo'lishi mumkin:
function removeFalsyValues(arr) { return arr.filter(Boolean); }
JavaScript'da funksiyani e'lon qilishning qanday usullari bor?
JavaScript'da funksiyani e'lon qilishning uchta asosiy usuli bor:
-
functionkeyword'i bilan function declaration sifatida:function myFunciton(..) {...} -
Arrow function sifatida:
const myFunction = () => {} -
Function obyekti yordamida:
const myFunction = new Function(...)
Fibonacci ketma-ketligini ma'lum bir songacha qaytaradigan funksiya yozing.
Bu funksiyani amalga oshirishning mumkin bo'lgan variantlaridan biri quyidagicha ko'rinishi mumkin:
function fibonacciSequence(n) {
// Handle edge cases for n < 2.
if (n <= 0) {
return [];
} else if (n === 1) {
return [0];
}
// Initialize the sequence with the first two numbers.
const sequence = [0, 1];
// Use a loop to generate the remaining numbers.
for (let i = 2; i < n; i++) {
// Each new number is the sum of the previous two numbers in the sequence.
const nextNumber = sequence[i - 1] + sequence[i - 2];
sequence.push(nextNumber);
}
// Return the resulting Fibonacci sequence.
return sequence;
}
Obyektlar massivini bitta obyektga qanday aylantirish mumkin?
Obyektlar massivini bitta obyektga aylantirish uchun reduce() metodidan foydalanishingiz mumkin. Bu yondashuv juda samarali, chunki u massiv bo'ylab iteration qiladi va bitta qiymatni (bu holda yangi obyektni) to'playdi.
Reducer funksiya ikkita argument qabul qiladi: accumulator va joriy element. Yakuniy obyektni asl massivdagi har bir element uchun yangi key-value juftligini qo'shish orqali qurasiz.
Bu metod ixcham bo'lib, zamonaviy JavaScript'da ko'pincha afzal ko'riladi.
Keling, uni amalga oshirishning mumkin bo'lgan variantini ko'rib chiqaylik:
function convertArrayToObject(arr) {
return arr.reduce((accumulator, currentItem) => {
const key = currentItem.id;
const value = currentItem.value;
accumulator[key] = value;
return accumulator;
}, {}); // The `{}` is the initial value of the accumulator.
}
Bu yondashuvda reduce() metodi massiv bo'ylab iteration qiladi. Birinchi argument — accumulator va joriy elementni qabul qiladigan funksiya. Ikkinchi argument {} esa accumulator'imizning boshlang'ich qiymati, ya'ni bo'sh obyekt.
Har bir iteration'da biz joriy elementdan key va value'ni olamiz (har bir elementda noyob id va value property'si bor deb faraz qilamiz) hamda accumulator'ga joriy elementning key va value'si bilan yangi property qo'shamiz.
// Example usage:
const data = [
{ id: 'a', value: 1 },
{ id: 'b', value: 2 },
{ id: 'c', value: 3 }
];
const singleObject = convertArrayToObject(data);
console.log(singleObject); // Expected output: { a: 1, b: 2, c: 3 }
Callback funksiyaning maqsadini tushuntiring.
Callback funksiya — boshqa funksiyaga argument sifatida uzatiladigan JavaScript funksiyasi. Uning maqsadi — tashqi funksiya callback funksiyani ma'lum bir vaqtda yoki biror amal (odatda asynchronous amal) yakunlangandan keyin bajarishiga imkon berish.
Bu pattern asynchronous JavaScript dasturlashidagi asosiy pattern'lardan biri bo'lib, blocking operatsiyalarni kodingizning qolgan qismini bloklamasdan bajarish imkonini beradi (I/O o'qishlari, tashqi API chaqiruvlari va hokazo kabi operatsiyalar).
map, filter va reduce o'rtasida qanday farq bor?
map asl massivning har bir elementiga funksiyani (odatda transformatsiyani) qo'llash orqali yangi massiv yaratadi.
filter faqat testdan (parametr sifatida uzatilgan funksiya bajaradigan testdan) o'tgan massiv elementlaridan iborat yangi massiv yaratadi.
reduce massivning barcha elementlarini bitta qiymatga keltiradi.
Takroriy elementlari bor massivdan noyob elementlarni qanday topasiz? Buni bajaradigan removeDuplicates(arr) funksiyasini yozing.
removeDuplicates funksiyasi Set tushunchasidan foydalanishi mumkin, chunki u o'z ichida takroriy qiymatlarga yo'l qo'ymaydi.
function removeDuplicates(arr) { return [...new Set(arr)]; }
Bu funksiya massiv qiymatlari bilan yangi Set yaratadi, bu esa uning tarkibini sukut bo'yicha noyob qiymatlar bilan cheklaydi, so'ngra spread operator (“...”) yordamida yangi hosil qilingan massivni qaytaradi.
Ikki string bir-birining anagrammasi ekanini tekshiradigan areAnagrams(str1, str2) funksiyasini yozing.
areAnagrams funksiyasi ikki string'ning saralangan ko'rinishlari bir xil ekanini tekshirishi kerak.
function areAnagrams(str1, str2) {
return str1.split('').sort().join('') === str2.split('').sort().join('');
}
Shu tarzda belgilar bo'ylab iteration qilishga hojat qolmaydi — shunchaki ikkalasini saralab, natijalarni tekshirasiz.
Spread operator nima va u qachon foydali?
Spread operator (...) iterable'ni (masalan, massivni) uning alohida elementlariga yoyadi. U massivlarni birlashtirish yoki nusxalar yaratish uchun foydali (buni 19-savolda amalda ko'rgan edik).
Sonlar va string'lardan iborat aralash kiruvchi massivdagi eng katta sonni topadigan funksiya yozing.
Faqat sonlardan iborat yangi massiv yaratish uchun filter metodidan foydalanishingiz mumkin. So'ngra eng katta sonni topish uchun return Math.max(...numbers) dan foydalaning. Bu yerda massiv qiymatlarini Math.max metodiga alohida parametrlar sifatida uzatish uchun yana spread operator'dan foydalanyapmiz.
JavaScript'dagi hoisting'ni tushuntiring.
JavaScript'da hoisting — kod bajarilishidan oldin, kompilyatsiya bosqichida o'zgaruvchi va funksiya declaration'lari ular joylashgan scope'ning eng yuqorisiga ko'chiriladigan mexanizm. Bu shuni anglatadiki, kodingizda o'zgaruvchi yoki funksiya "rasman" e'lon qilinishidan oldin ham o'zgaruvchidan foydalanishingiz yoki funksiyani chaqirishingiz mumkin.
Shunday bo'lsa-da, bitta juda muhim nozik jihatni tushunib olish kerak: faqat declaration'lar hoist qilinadi, initialization'lar emas.
Masalan, var bilan e'lon qilingan o'zgaruvchidan e'lon qilinishidan oldin "foydalanish" mumkin, lekin kod unga qiymat beriladigan qatorga yetib kelmaguncha uning qiymati undefined bo'lib turadi. Bu JavaScript dasturlashida bug'larning keng tarqalgan manbaidir.
Boshqa tomondan, let va const declaration'lari ham hoist qilinadi, lekin ular block boshidan to e'lon qilingunga qadar "temporal dead zone"da bo'ladi va ularga murojaat qilishga urinish xato chiqaradi. Bu xatti-harakat let va const'ni xavfsizroq va oldindan aytib bo'ladiganroq qiladi.
concat() ishlatmasdan ikkita massivni bitta massivga qanday birlashtirasiz? mergeArrays nomli funksiya yozing.
mergeArrays funksiyasi spread operator'dan foydalanishi mumkin:
function mergeArrays(arr1, arr2) { return [...arr1, ...arr2]; }.
Shu tarzda ikkala massivning tarkibi yangi massiv ichiga alohida qiymatlar sifatida yoyiladi — massivlar bo'ylab qo'lda iteration qilish yoki shunga o'xshash biror narsaga hojat yo'q.
JavaScript obyektini JSON string'ga qanday stringify qilasiz?
JavaScript obyekti yoki qiymatini JSON string'ga aylantirish uchun JSON.stringify(obj) dan foydalanasiz.
Bo'sh string'ni qanday yaratasiz?
O'zgaruvchi e'lon qilib, unga "" qiymatini berishingiz yoki String() dan foydalanishingiz mumkin.
String'lar massivini bo'sh joylar bilan ajratilgan bitta string'ga aylantiradigan converts(arr) funksiyasini yozing.
converts funksiyasini quyidagicha yozish mumkin:
function converts(arr) { return arr.join(' '); }.
Asl massivdan barcha elementlari ikki baravar oshirilgan yangi massivni qanday olgan bo'lardingiz?
Buni hal qilish uchun map metodini quyidagicha chaqirishingiz mumkin:
const doubled = originalArray.map(item => item * 2);.
map metodi sukut bo'yicha yangi massiv qaytaradi, shuning uchun ikkala muammoni bir vaqtning o'zida hal qilasiz.
Massivda ma'lum bir element bor-yo'qligini qanday tekshirish mumkin?
Buning uchun true yoki false qaytaradigan oddiy funksiya bo'lgan includes() metodidan foydalanishingiz mumkin.
JavaScript funksiyasi nima?
JavaScript funksiyasi — muayyan vazifani bajarish uchun mo'ljallangan kod bloki. Uni kodingiz davomida qayta-qayta chaqirish mumkin.
O'rta darajadagi savollar
Ketma-ket funksiya chaqiruvlarini debounce qiladigan funksiyani qanday amalga oshirasiz?
Debounce funksiyasi — boshqa funksiyani chaqirish chastotasini cheklaydigan JavaScript funksiyasi.
U odatda bir qator funksiya chaqiruvlarining hammasi bir vaqtning o'zida ishga tushib ketishining oldini olish uchun setTimeout va clearTimeout funksiyalaridan birgalikda foydalanadi.
Event loop nima va u asynchronous JavaScript bilan qanday bog'liq?
Event loop — JavaScript runtime arxitekturasining muhim qismi bo'lib, u asynchronous operatsiyalarni boshqarishga yordam beradi.
Event loop call stack bo'sh yoki bo'sh emasligini doimiy ravishda tekshirib turadi va task queue'dagi vazifalarni unga joylaydi.
Function declaration va function expression o'rtasidagi farqni tushuntiring.
Ikkalasi ham funksiyani aniqlash usullari, biroq:
-
Function declaration hoist qilinadi, ya'ni uni e'lon qilinishidan oldin ham chaqirishingiz mumkin.
-
Function expression esa hoist qilinmaydi, shuning uchun uni chaqirishdan oldin aniqlab qo'yishingiz kerak.
Oddiy JavaScript funksiyasida va arrow function'da this keyword'i qanday ishlaydi?
Oddiy JavaScript funksiyasi o'zining this keyword'ini qanday chaqirilganiga qarab belgilaydi va siz undan funksiyaning o'ziga murojaat qilish uchun foydalanishingiz mumkin. Arrow function'ning esa o'z this keyword'i yo'q; u o'z scope'ini (this keyword'i nimaga murojaat qilishini) o'rab turgan scope'dan meros qilib oladi.
JavaScript funksiyasi yordamida private o'zgaruvchini qanday yaratgan bo'lardingiz? Funksiya yoki metodlarga ega obyekt qaytaradigan funksiyani ko'rsating.
Bunga closure yordamida erishishingiz mumkin. Funksiya yoki metodga ega obyekt qaytaradigan funksiya o'zining parent scope'idagi o'zgaruvchiga murojaat qila oladi.
function createCounter() {
// `count` is the private variable. It is only accessible within this function.
let count = 0;
// The function returns an object with methods.
// These methods are the only way to interact with the private `count` variable.
return {
// The `increment` method has access to `count` through the closure.
increment: function() {
count++;
console.log(`Count incremented to: ${count}`);
},
// The `getValue` method also has access to `count`.
getValue: function() {
return count;
}
};
}
obj va key qabul qilib, o'sha key'ning qiymatini qaytaradigan funksiya yozing.
function getValueByKey(obj, key) {
// Check if the object and key are valid and the object has the key as its own property.
// We use `Object.prototype.hasOwnProperty.call()` for a safer check
// against objects that might not have a `hasOwnProperty` method.
if (typeof obj === 'object' && obj !== null && Object.prototype.hasOwnProperty.call(obj, key)) {
return obj[key];
} else {
// If the key doesn't exist or the inputs are invalid, return undefined.
return undefined;
}
}
Closure'larni tushuntiring va ular JavaScript dasturlashida qayerda ishlatilishi mumkinligiga misol keltiring.
Closure — o'zi yaratilgan muhitni "eslab qoladigan" maxsus turdagi funksiya. Bu muhit uning parent funksiyasining lokal o'zgaruvchilarini o'z ichiga oladi.
Bu shuni anglatadiki, parent funksiya o'z ishini tugatgandan keyin ham ichki funksiya parent scope'idagi o'zgaruvchilarga murojaat qila oladi va ulardan foydalana oladi.
Bu JavaScript'dagi fundamental tushuncha bo'lib, private o'zgaruvchilar yaratish va data encapsulation'ni amalga oshirish kabi maqsadlarda ishlatiladi.
Spread operator va rest parameter o'rtasida qanday farq bor?
Spread operator iterable'ni alohida elementlar ro'yxatiga yoyadi, rest parameter esa o'zgaruvchan sondagi argumentlarni bitta massivga yig'adi. Ikkinchisi o'zgaruvchan sondagi parametrlarga ega funksiyalarni aniqlash uchun ishlatiladi.
Obyektning deep copy'sini qanday amalga oshirasiz? Shallow copy nima uchun muammoli bo'lishi mumkinligini tushuntiring.
Obyektning deep copy'sini yaratish uchun JSON.parse(JSON.stringify(obj)) dan foydalanishingiz mumkin.
Shallow copy muammoli, chunki u faqat yuqori darajadagi property'larni nusxalaydi va hamon asl massiv bilan bir xil nested obyektlarga ishora qiladi.
Callback funksiya nima? Callback hell'ni va undan qochish yechimini tushuntiring.
Callback funksiya — asynchronous funksiyaga parametr sifatida uzatiladigan funksiya. Asynchronous operatsiya tugagach, callback funksiya bajariladi.
Callback hell yozilgan kod callback funksiyalarning chuqur ichma-ich joylashgan, o'qib bo'lmaydigan tuzilmasiga aylanib qolganda yuzaga keladi; bu ko'pincha bir nechta asynchronous operatsiyaning biri boshqasini o'z callback'lari ichidan chaqirishi natijasida sodir bo'ladi.
Yechim — Promise'lar yoki async/await'dan foydalanish.
Custom Promise.all()'ni qanday amalga oshirasiz?
Yangi Promise qaytaradigan funksiya yozasiz. Uning ichida promise'lar bo'ylab iteration qilasiz va ularning barchasi resolve bo'lgach, asosiy Promise'ni natijalar bilan resolve qilasiz.
Ikkita parametr qabul qilib, ularning ko'paytmasini qaytaradigan function multiply(a, b) funksiyasini yozing.
Oddiy multiply(a, b) funksiyasini const multiply = (a, b) => a * b; ko'rinishida yozish mumkin.
Throttle funksiyasini qanday amalga oshirasiz?
Throttle funksiyasi JavaScript funksiyasining belgilangan vaqt oralig'ida ko'pi bilan bir marta chaqirilishini ta'minlaydi. Bu ko'pincha timestamp yoki flag yordamida amalga oshiriladi.
call(), apply() va bind() o'rtasidagi farqni tushuntiring.
Uchala metod ham JavaScript funksiyasining this kontekstini o'zgartiradi. call() va apply() funksiyani darhol bajaradi. call() argumentlarni alohida-alohida qabul qiladi, apply() esa ularni kiruvchi massiv sifatida qabul qiladi (bu, ayniqsa, parametr sifatida uzatiladigan qiymatlarning dinamik ro'yxati bo'lganda foydali).
Va nihoyat, bind() this konteksti boshqa narsaga doimiy ravishda bog'langan yangi funksiyani qaytaradi.
Kattaroq massivning dastlabki beshta elementidan iborat yangi massiv qaytaradigan funksiya yozing.
Kiruvchi massivni qabul qilib, uning dastlabki 5 ta elementini qaytaradigan funksiyani quyidagicha yozish mumkin:
const slideIt(arr) => arr.slice(0, 5)
So'zlardan iborat string'ni qabul qilib, o'sha so'zlarning teskari tartibdagi massivini qaytaradigan funksiyani qanday yaratasiz?
const words = "hello world" berilgan bo'lsa, words.split(' ').reverse(); ni qaytarishingiz mumkin.
Promise'lar zanjiridagi xatolarni qanday boshqargan bo'lardingiz?
Har qanday xatoni ushlab olish uchun Promise zanjirining oxirida .catch() metodidan foydalanishingiz mumkin.
== va === o'rtasidagi farqni tushuntiring.
JavaScript'da == va === o'rtasidagi asosiy farq shundaki, == qiymatlar tengligini tekshiradi (ya'ni murojaat qilingan qiymatlar bir xil ekanini), === esa ham qiymat, ham type tengligini tekshiradi. Birinchisi type'lar bir xil bo'lmasa, ularni coerce qiladi, ikkinchisi esa bunday qilmaydi.
Sonlardan iborat kiruvchi massivni qabul qilib, reduce metodi yordamida ularning yig'indisini qaytaradigan sumAll(arr) funksiyasini yozing.
Mana bu masalani yechadigan namunaviy kod:
function sumAll(arr) {
return arr.reduce((sum, current) => sum + current, 0);
}
localStorage, sessionStorage va cookie'lar o'rtasida qanday farq bor?
localStorage va sessionStorage key/value juftliklarini client tomonida saqlaydi. Ular o'rtasidagi asosiy farq shundaki, localStorage brauzer yopilgandan keyin ham saqlanib qoladi, sessionStorage esa tozalanadi.
Bundan tashqari cookie'lar ham bor: ular server'ga yuboriladigan har bir HTTP so'rov bilan birga jo'natiladi va ularning hajmi cheklangan.
Memoization decorator'ini qanday amalga oshirasiz?
Oldingi funksiya chaqiruvlari natijalarini saqlash uchun keshdan foydalanadigan va keshlangan logikaga ega funksiyani qaytaradigan funksiya yozasiz. Kesh oddiy obyekt bo'lishi mumkin.
Prototype'siz obyektni qanday yaratasiz?
Buning uchun Object.create(null) dan foydalanishingiz mumkin. U prototype chain'ga ega bo'lmagan obyekt yaratadi, bu esa kutilmagan xatti-harakatlarning oldini olishi mumkin.
Takroriy elementlardan qochgan holda asl massivni yangi massiv bilan birlashtirish uchun ishlatilishi mumkin bo'lgan funksiya yozing.
Takroriy elementlarni boshqarish uchun Set'dan, massivlarni birlashtirish uchun esa spread operator'dan foydalanishingiz mumkin.
function mergeAndRemoveDuplicates(originalArray, newArray) {
// Use the spread operator to combine the elements of both arrays.
const mergedArray = [...originalArray, ...newArray];
// A Set can only hold unique values. We use it to automatically remove duplicates.
const uniqueElements = new Set(mergedArray);
// Convert the Set back into a new array using the spread operator.
return [...uniqueElements];
}
JavaScript'da o'zgaruvchining type'ini qanday aniqlaysiz?
JavaScript strongly typed til bo'lmasa-da, typeof operatori yordamida o'zgaruvchining type'ini baribir aniqlashingiz mumkin.
JavaScript nima uchun single-threaded dasturlash tili ekanini tushuntiring.
JavaScript single-threaded til, chunki unda bitta call stack va bitta memory heap bor. Bu uning bir vaqtning o'zida faqat bitta vazifani bajara olishini anglatadi.
Higher-order funksiyalar nima?
Higher-order funksiyalar — boshqa funksiyalarni argument sifatida qabul qila oladigan yoki funksiyalarni qaytaradigan funksiyalar.
Ikki obyekt deep equal ekanini qanday aniqlagan bo'lardingiz?
Ikki obyekt deep equal ekanini aniqlash JavaScript dasturlashida keng tarqalgan muammo, chunki === operatori faqat ular xotiradagi aynan bir xil obyekt ekanini tekshiradi, ularning tarkibi bir xil, ammo o'zlari bir xil turdagi obyektning 2 ta alohida instance'i ekanini emas.
Avval === operatoridan foydalanishingiz mumkin: agar u true bo'lsa, demak bu bitta obyekt, ya'ni ular shubhasiz deep equal.
Shuningdek, obyektlardan faqat bittasi null ekanini ham tekshirishingiz mumkin — bu ular shubhasiz deep equal emasligini bildiradi.
Va nihoyat, obyektlarning key'lari ro'yxatini olib, ular bo'ylab iteration qilishingiz va har bir sub-tree'ning deep equality'sini hisoblash uchun xuddi shu funksiyani recursive tarzda chaqirishingiz kerak bo'ladi.
Ikkita parametr qabul qilib, ularning yig'indisini qaytaradigan function sum(a, b) funksiyasini yozing.
Ikki sonni qo'shadigan funksiya quyidagicha ko'rinishi mumkin:
function sum(a, b) { return a + b; }
Bo'sh massivni qanday olgan bo'lardingiz?
Buning uchun [] yoki new Array() dan foydalanishingiz mumkin.
Sonlar massivini qabul qilib, uni kamayish tartibida saralaydigan funksiya yozing.
function sortDescending(arr) {
/* The sort() method sorts the elements of an array in place.
For numeric sorting, we need to provide a compare function.
The compare function here, `(a, b) => b - a`, tells JavaScript to sort in descending order.
– If b - a is positive, b comes before a.
- If b - a is negative, a comes before b.
- If b - a is zero, their order remains unchanged.
*/
return arr.sort((a, b) => b - a);
}
Murakkab darajadagi savollar
JavaScript'da prototypal inheritance qanday ishlashini tushuntiring.
Prototypal inheritance — JavaScript'da inheritance hosil qilish usuli.
Har bir obyektning prototype obyekti bo'ladi va obyekt metod hamda property'larni undan meros qilib oladi. Obyektning prototype'i sifatida boshqa obyektni belgilash mumkin, bu esa prototype chain hosil qiladi.
Circular reference'larni o'z ichiga olgan murakkab obyektning deep clone'ini qanday yaratasiz?
Odatda Lodash'ning cloneDeep kabi kutubxonadan foydalanasiz. Qo'lda yozilgan yechimda circular reference'larni boshqarish uchun klonlangan obyektlarga reference'larni WeakMap'da saqlab borish talab qilinadi.
Event Loop'dagi Microtask Queue va Macrotask Queue'ning rolini tushuntiring.
Microtask Queue Promise callback'lari va async/await kodi kabi yuqori ustuvorlikka ega vazifalarni saqlaydi. Macrotask Queue (yoki task queue) esa setTimeout va setInterval kabi pastroq ustuvorlikdagi vazifalarni saqlaydi.
Microtask'lar navbatdagi macrotask'dan oldin qayta ishlanadi.
Promise.race()'ni noldan amalga oshiradigan funksiyani qanday yozgan bo'lardingiz?
Buning uchun new Promise((resolve, reject) => { ... }) qaytarishingiz mumkin. Uning ichida kiruvchi promise'lar bo'ylab loop qilib, ularga then va catch handler'larini biriktirasiz; bu handler'lar birinchi element tayyor bo'lishi bilanoq asosiy Promise'ni resolve yoki reject qiladi.
Event bubbling va event capturing o'rtasida qanday farq bor?
Ikkalasi ham elementlarning event'larni qabul qilish tartibini tavsiflaydi. Event bubbling ichki elementdan boshlanadi va tashqariga, parent elementlar tomon tarqaladi.
Event capturing buning aksi: u eng tashqi elementdan boshlanib, ichkariga qarab tarqaladi.
Memory leak nima ekanini va JavaScript'da uning oldini qanday olishni tushuntiring.
Memory leak obyektlar yoki o'zgaruvchilar ilovaga endi kerak bo'lmasa-da, ularga hamon reference bo'lib turganda yuzaga keladi va bu garbage collector'ning o'sha xotirani bo'shatishiga to'sqinlik qiladi. Ularga tozalanmagan event listener'lar, unutilgan timer'lar yoki global o'zgaruvchilar, shuningdek boshqa potentsial xavflar sabab bo'lishi mumkin.
new keyword'ining ichki ishlash mexanizmini tavsiflang.
new keyword'i — maxsus operator. U JavaScript funksiyasini chaqirishdan oldin ishlatilganda prototype'i constructor'ning prototype'iga bog'langan yangi obyekt yaratadi, this'ni yangi obyektga bog'laydi, constructor'ni bajaradi va yangi yaratilgan obyektni qaytaradi.
Service Worker'lar nima va ular veb unumdorligini qanday oshiradi?
Service Worker'lar — main thread'dan alohida, fonda ishlaydigan web worker turi. Ular Progressive Web App'lar (PWA) yaratishning asosiy qismi bo'lib, offline support va asset'larni keshlash kabi imkoniyatlarni beradi.
Currying'ni qanday amalga oshirasiz?
Currying — bir nechta argumentli JavaScript funksiyasini har biri bitta argument qabul qiladigan funksiyalar ketma-ketligiga aylantirish texnikasi.
Functional programming nima? Uning tamoyillarini JavaScript'da qanday qo'llash mumkin?
Functional programming — JavaScript funksiyalariga first-class citizen sifatida qaraydigan dasturlash paradigmasi.
Asosiy tushunchalar qatoriga pure function'lar (bajarilganda hech qanday side effect'ga ega bo'lmagan funksiyalar) va immutability kiradi.
map, filter va reduce metodlari bunga ajoyib misol bo'la oladi.
WeakMap va WeakSet'ning maqsadi nima?
WeakMap key'lari object type bo'lishi shart, WeakSet elementlari ham object type bo'lishi shart. Ikkalasi ham obyektlarga "weak" reference'larni saqlaydi, ya'ni agar obyektga boshqa hech qanday reference qolmasa, u garbage collection orqali tozalanishi mumkin, bu esa memory leak'larning oldini oladi.
Minglab elementlardan iborat ro'yxatning rendering unumdorligini qanday optimallashtirgan bo'lardingiz?
Ro'yxatning faqat ko'rinib turgan elementlarini render qilish uchun virtualization (yoki windowing) kabi texnikalardan foydalanishingiz mumkin. Bu DOM elementlari sonini keskin kamaytiradi va rendering unumdorligini oshiradi.
Express.js server uchun oddiy middleware funksiyasini qanday yozgan bo'lardingiz?
Oddiy middleware funksiyasi ikkita argument — req va res hamda uchinchi next callback funksiyasini qabul qiladi. U biror logikani bajaradi, so'ngra boshqaruvni stack'dagi keyingi middleware'ga uzatish uchun next()'ni chaqiradi.
Katta, chuqur nested obyektda property'ga xavfsiz murojaat qilish kerak bo'lgan muammoni qanday hal qilgan bo'lardingiz?
Buning uchun optional chaining (?.) dan foydalanishingiz mumkin: u oraliq property null yoki undefined bo'lsa ham xato chiqarmasdan nested property'larga xavfsiz murojaat qiladi.
Observer pattern'ni va uni qanday amalga oshirishingizni tushuntiring.
Observer pattern — software design pattern bo'lib, unda obyekt ("subject") o'ziga bog'liq obyektlar ("observer'lar") ro'yxatini yuritadi va ularni state'dagi har qanday o'zgarishlar haqida xabardor qiladi.
Uni subscribe va notify metodlariga ega oddiy subject sinfi yordamida amalga oshirishingiz mumkin.
JavaScript kontekstida eng keng tarqalgan ma'lumotlar tuzilmalari va algoritmlar qaysilar?
JavaScript'da keng tarqalgan ma'lumotlar tuzilmalari qatoriga tartiblangan ro'yxatlarga o'xshash massivlar, key-value juftliklarini saqlaydigan obyektlar, shuningdek stack'lar, queue'lar, linked list'lar va tree'lar kabi murakkabroq tuzilmalar kiradi.
Ma'lumotlar tuzilmasini tanlash juda muhim, chunki u siz yozadigan kodning samaradorligiga va dasturingizda muammolarni qanday hal qilishingizga ta'sir qiladi.
Algoritm — muayyan muammoni hal qilish yoki muayyan vazifani bajarish (odatda ma'lumotlar tuzilmalaringiz bilan) uchun aniq belgilangan, bosqichma-bosqich ko'rsatmalar to'plami.
JavaScript'da kod yozishda bu massivni saralaydigan, ro'yxatdan elementni qidiradigan yoki tree bo'ylab traverse qiladigan funksiya yozishni anglatishi mumkin. Intervyu oluvchilar bu haqda muammolarni hal qilish va samaradorlik haqida qanday fikrlashingizni ko'rish uchun so'rashadi. Ular sizning nafaqat ishlaydigan, balki yaxshi unumdorlik ko'rsatadigan kod ham yoza olishingizni bilishni xohlashadi.
Type coercion bo'sh string kabi primitive qiymatlarni qanday boshqaradi?
Operatsiyaga qarab, type coercion mexanizmi string'ni turli yo'llar bilan boshqaradi.
Masalan, raqamli operatsiyalarda (ya'ni ko'paytirish yoki bo'lishda) u 0 sifatida, qo'shishdan foydalanayotgan bo'lsangiz esa string sifatida qabul qilinadi. Hatto Boolean kontekstida false sifatida ham qaralishi mumkin.
Class syntax va prototypal inheritance o'rtasidagi asosiy farqlar qanday?
Class syntax'i JavaScript'dagi prototypal inheritance ustidagi shunchaki syntactic sugar.
Class syntax'i klassik OOP inheritance ko'rinishini bersa-da, uning ostidagi mexanizm hamon prototype'larga tayanadi. Bu dasturchilar uchun prototypal inheritance tushunchasini soddalashtiradi va ko'plab yangi JavaScript dasturchilariga butunlay yangi dasturlash paradigmasini o'rganish o'rniga tanishroq tushunchalar bilan tildan foydalanish yo'lini ochadi.
Single-page application'da authentication'ni qanday boshqarasiz?
Single Page Application (SPA)'da authentication'ni boshqarishning eng keng tarqalgan va zamonaviy usuli — token-based authentication, ko'pincha JSON Web Token (JWT) yordamida.
Jarayon odatda quyidagicha ishlaydi:
-
Foydalanuvchi tizimga kirganda, SPA uning credential'larini (username va parol) backend'ga yuboradi.
-
Backend credential'larni tekshiradi. Agar ular to'g'ri bo'lsa, JWT yaratadi va uni client'ga qaytarib yuboradi.
-
So'ngra SPA bu JWT'ni xavfsiz joyda, odatda
localStorageyokisessionStorage'da saqlaydi. -
Himoyalangan API endpoint'iga yuboriladigan keyingi har bir so'rovda SPA JWT'ni HTTP so'rovning
Authorizationheader'iga qo'shadi (har bir so'rovda credential'larni yuborish o'rniga). -
Backend middleware yordamida so'rovni ushlab oladi va token'ning yaroqliligi hamda imzosini tekshiradi. Agar token yaroqli bo'lsa, so'rovga davom etishga ruxsat beriladi. Agar u yaroqsiz bo'lsa yoki umuman bo'lmasa, kirish rad etiladi.
Bu yondashuvning ajoyib tomoni shundaki, u stateless, ya'ni server foydalanuvchi session'larini kuzatib borishi shart emas. Unga faqat token'ni tekshirish kifoya. Bu uni yuqori darajada scalable qiladi va SPA'larning asynchronous tabiatiga juda mos keladi.
Obyektni shallow va deep copy qilish o'rtasidagi farqni tushuntiring.
Obyektni shallow va deep copy qilish o'rtasidagi asosiy farq shundaki, shallow copy obyektning yangi instance'ini yaratadi, lekin nested obyektlarga bo'lgan reference'larni nusxalaydi. Shuning uchun asl obyektning nested qismlarini o'zgartirish ikkala nusxaga ham ta'sir qiladi.
Deep copy yangi obyekt yaratadi va barcha nested obyektlarni recursive tarzda nusxalaydi, shuning uchun asl element va nusxa bir-biridan butunlay mustaqil bo'ladi. Bu esa, o'z navbatida, asl obyektdagi har qanday o'zgarish (qaysi darajada bo'lishidan qat'i nazar) nusxaga bevosita ta'sir qilmasligini anglatadi.