۲۰ سوال مهم مصاحبه جاوااسکریپت
جاوااسکریپت شده مثل زبان مادری دنیای وب. برای همین توی مصاحبه های فرانت اند و فول استک، معمولا چند تا سوال تکراری همیشه هست که اگر قبلش مرورشان کرده باشی نصف استرست کم می شود.
اینجا ۲۰ تا از سوال های رایج مصاحبه جاوااسکریپت را جمع کردم و برای هر کدام خیلی جمع و جور و خودمونی توضیح دادم که سر مصاحبه لازم نباشد تازه فکر کنی.
سوال ۱
تفاوت var و let و const چیست
این سه تا بیشتر از همه توی سه چیز با هم فرق دارند: محدوده دسترسی، امکان دوباره تعریف کردن و رفتارشان در هوئیستینگ.
خلاصه اش این است:
varتابع اسکوپ است. هم می شود دوباره مقداردهی کرد هم دوباره تعریف. استفاده زیاد از آن باعث باگ های ریز می شود.letبلاک اسکوپ است. می شود دوباره مقداردهی کرد ولی نمی شود دوباره تعریف کرد.constبلاک اسکوپ است و نه دوباره تعریف می شود کرد نه دوباره مقداردهی. البته اگر روی آبجکت یا آرایه باشد، خود رفرنس ثابت است ولی داخلش را می شود عوض کرد.
در کدهای جدی معمولا از let و const استفاده می کنند و var را تقریبا کنار گذاشته اند.
سوال ۲
هوئیستینگ در جاوااسکریپت یعنی چه
هوئیستینگ یعنی جاوااسکریپت قبل از این که خط به خط کد را اجرا کند، تعاریف متغیرها و تابع ها را می برد بالای اسکوپ.
مثلا این کد:
console.log(a)
var a = 5
ارور نمی دهد و خروجی undefined می شود چون انگار این طور نوشته شده:
var a
console.log(a)
a = 5
برای var متغیر هوئیست می شود و مقدار پیش فرضش تا قبل از مقداردهی undefined است.
برای let و const هم هوئیست می شوند ولی تا قبل از خط تعریف داخل محدوده ای به اسم temporal dead zone هستند و اگر ازشان استفاده کنی ارور می گیری.
تابع هایی که با function معمولی تعریف می شوند هم کامل هوئیست می شوند و می شود قبل از خط تعریفشان آن ها را صدا زد.
سوال ۳
اسکوپ یا حوزه دسترسی در جاوااسکریپت چیست
اسکوپ یعنی این که یک متغیر از کجاها قابل دسترسی است.
به طور ساده سه مدل مهم داریم:
- اسکوپ سراسری که متغیر تقریبا همه جای فایل دیده می شود.
- اسکوپ تابع که متغیر فقط داخل همان تابع دیده می شود.
- اسکوپ بلاک که متغیر فقط داخل بلاک هایی مثل if و for دیده می شود. این برای
letوconstاست.
مثلا اگر داخل یک حلقه for با let یک متغیر تعریف کنی، هر تکرار حلقه در عمل نسخه خودش را دارد. ولی با var این طور نیست و ممکن است رفتار عجیبی ببینی.
سوال ۴
closure در جاوااسکریپت چیست
کلوزر یعنی این که یک تابع به متغیرهای اسکوپ بیرونی خودش بعد از این که آن اسکوپ تمام شده هم دسترسی داشته باشد.
مثلا وقتی داخل یک تابع، تابع دیگری را بر می گردانی و آن تابع داخلی از متغیرهای تابع بیرونی استفاده می کند، داری کلوزر درست می کنی.
از کلوزرها برای چیزهایی مثل:
- درست کردن متغیرهای خصوصی
- پیاده سازی فانکشن هایی مثل
onceیاdebounce - ساختن فانکشن های تنظیم شده بر اساس یک مقدار اولیه
خیلی استفاده می کنند. توی مصاحبه اگر هم تعریفش را بگویی هم یک مثال کاربردی بزنی، خیلی امتیاز می گیری.
سوال ۵
کلمه this در جاوااسکریپت به چه چیزی اشاره می کند
جواب تئوری خیلی ساده است: this به کانتکستی اشاره می کند که تابع داخل آن صدا زده شده است، نه جایی که تعریف شده.
ولی در عمل این یعنی چه:
- وقتی یک تابع را روی یک آبجکت صدا می زنی،
thisمعمولا همان آبجکت است. - در حالت strict اگر تابع معمولی را بدون آبجکت صدا بزنی،
thisمقدارundefinedاست. - در تابع های arrow مقدار
thisاز بیرون ارث می آید و با توجه به نحوه صدا زدن تابع عوض نمی شود.
مصاحبه کننده ها معمولا یک قطعه کد می دهند و می پرسند این جا this دقیقا چیست. تمرکز اصلی سر تفاوت تابع معمولی و arrow است.
سوال ۶
توضیح بده inheritance در جاوااسکریپت چگونه است
در جاوااسکریپت خبری از کلاس به شکل سنتی نیست، همه چیز روی زنجیره prototype سوار است. البته از وقتی سینتکس class اضافه شده، ظاهرش شبیه زبان های کلاس محور شده ولی پشت صحنه همان prototype chain است.
به طور خلاصه:
- هر آبجکت یک لینک به یک آبجکت دیگر به نام
prototypeدارد. - اگر خاصیتی روی خود آبجکت پیدا نشود، جاوااسکریپت روی prototype دنبالش می گردد.
- این زنجیره تا جایی می رود که به
Object.prototypeبرسد.
در جواب مصاحبه کافی است بگویی که جاوااسکریپت prototype based است و بعد اشاره کنی که class فقط یک سینتکس تمیزتر روی همین مکانیزم است.
سوال ۷
event loop چیست و چرا مهم است
جاوااسکریپت تک نخ است یعنی هم زمان فقط یک کار را روی call stack اجرا می کند. برای این که بتواند کارهای زمان بر مثل درخواست شبکه را هندل کند، از event loop کمک می گیرد.
ایده کلی:
- call stack جایی است که کدهای در حال اجرا قرار می گیرند.
- کارهای async مثل
setTimeoutیا درخواست شبکه وقتی آماده شدند، callback هایشان می رود در صف task ها یا microtask ها. - event loop مدام چک می کند که اگر call stack خالی شد، از صف ها کار بعدی را وارد stack کند.
اگر بتوانی مختصر توضیح بدهی که چرا یک setTimeout با زمان صفر هم باز بعد از کدهای sync اجرا می شود، یعنی مفهوم event loop را گرفتی.
سوال ۸
تفاوت callback و Promise و async await چیست
هر سه برای مدیریت کارهای غیر همزمان استفاده می شوند ولی سطح خوانایی و راحتی شان فرق دارد.
- callback ساده ترین و قدیمی ترین روش است. ولی اگر چند کار پشت هم داشته باشی خیلی سریع به چیزی شبیه callback hell می رسی و کد خوانا نمی ماند.
- Promise ساختار منظم تری می دهد. می توانی با
thenوcatchزنجیره ای کارها را بنویسی و خطاها را یک جا بگیری. asyncوawaitدر ظاهر کد را شبیه کد همزمان می کنند. داخل یک تابعasyncمی توانی جلوی یک Promise بنویسیawaitو نتیجه اش را مستقیم مثل یک مقدار عادی استفاده کنی.
توی مصاحبه معمولا دوست دارند ببینند که نه فقط تفاوت تئوری را می دانی، بلکه می توانی توضیح بدهی کدام را کجا ترجیح می دهی.
سوال ۹
تفاوت ==و=== چیست
== مقایسه با تبدیل نوع خودکار است و === مقایسه بدون تغییر نوع.
یعنی:
5 == "5"درست است چون رشته به عدد تبدیل می شود.5 === "5"غلط است چون نوع ها با هم فرق دارند.
مصاحبه ها این را می پرسند تا مطمئن شوند عادت داری از === استفاده کنی و روی رفتار گاهی عجیب == حساب باز نمی کنی.
سوال ۱۰
مفهوم truthy و falsy در جاوااسکریپت چیست
در جاوااسکریپت هر مقداری اگر داخل یک شرط قرار بگیرد، به صورت ضمنی به true یا false تبدیل می شود.
مقادیر falsy معروف:
0- رشته خالی
"" nullundefinedNaN- مقدار
falseخودش
هر چیزی غیر از این ها truthy حساب می شود.
مثلا یک آرایه خالی یا یک آبجکت خالی truthy هستند و این جا خیلی ها اشتباه می کنند.
سوال ۱۱
تفاوت map و filter و reduce در آرایه ها چیست
این سه تا متد پر استفاده روی آرایه ها هستند و دانستنشان تقریبا اجباری است.
mapروی هر عضو آرایه یک تابع اجرا می کند و آرایه جدید با همان طول بر می گرداند.filterفقط آن هایی را نگه می دارد که شرطش درست باشد و آرایه جدید کوتاه تر بر می گردد.reduceیک مقدار نهایی می سازد، مثلا جمع یا تبدیل آرایه به آبجکت.
اگر بتوانی برای هر کدام یک مثال سریع در ذهن داشته باشی، جواب این سوال برایت خیلی راحت می شود.
سوال ۱۲
spread و rest operator چه فرقی دارند
هر دو از سه نقطه استفاده می کنند ولی معنی شان بستگی به جایی دارد که استفاده می شوند.
- وقتی در سمت راست مقداردهی یا داخل آرایه و آبجکت استفاده شود، نقش spread دارد و یک چیز قابل تکرار را باز می کند. مثلا
...arr. - وقتی در تعریف تابع قبل از آخرین آرگومان بیاید، نقش rest دارد و بقیه آرگومان ها را در قالب یک آرایه جمع می کند.
برای مثال، می شود گفت spread مثل باز کردن محتویات است و rest مثل جمع کردن چند چیز در یک بسته جدید.
سوال ۱۳
تفاوت کپی سطحی و کپی عمیق چیست
در جاوااسکریپت برای انواع اولیه مثل عدد و رشته، کپی کردن واقعا یک کپی مستقل می سازد. ولی برای آبجکت و آرایه، متغیر در اصل یک رفرنس نگه می دارد.
کپی سطحی یعنی فقط لایه اول کپی شود و اگر داخل آبجکت، آبجکت دیگری باشد، هنوز همان رفرنس قبلی است.
کپی عمیق یعنی همه لایه ها جداگانه کپی شوند.
مصاحبه ممکن است بپرسد با Object.assign یا spread چه جور کپی ای می سازیم. جواب این است که این ها معمولا کپی سطحی می دهند.
سوال ۱۴
تفاوت مقداردهی بر اساس مقدار و بر اساس رفرنس چیست
انواع اولیه مثل number و string بر اساس مقدار منتقل می شوند. یعنی اگر یک متغیر جدید از روی آن ها بسازی و مقدارش را عوض کنی، روی قبلی اثر ندارد.
ولی آبجکت ها و آرایه ها بر اساس رفرنس منتقل می شوند. یعنی اگر یک متغیر دیگر برابر یک آبجکت بگذاری و بعد یکی از خاصیت هایش را عوض کنی، هر دو متغیر همان تغییر را می بینند چون به یک جا اشاره می کنند.
مصاحبه کننده با این سوال می خواهد بداند که می فهمی چرا بعضی وقت ها یک جای کد را عوض می کنی و یک جای دیگر ناخواسته تغییر می کند.
سوال ۱۵
بگو event bubbling و capturing یعنی چه
وقتی روی یک المنت در مرورگر کلیک می کنیم، رویداد از سه مرحله رد می شود:
- مرحله capturing که از ریشه داکیومنت به سمت المنت داخلی می آید.
- مرحله target که روی خود المنت اتفاق می افتد.
- مرحله bubbling که از المنت هدف دوباره به سمت بالا بر می گردد.
به طور پیش فرض اغلب لیسنرها در مرحله bubbling اجرا می شوند.
مهم ترین نکته کاربردی این است که بفهمی چطور می شود با event delegation روی یک والد، همه رویدادهای فرزندان را مدیریت کرد.
سوال ۱۶
event delegation چیست و چرا استفاده می شود
به جای این که روی تک تک دکمه ها یا آیتم ها listener بگذاری، می توانی روی والد مشترکشان یک listener بگذاری و داخلش ببینی روی کدام بچه کلیک شده است.
این کار دو فایده بزرگ دارد:
- تعداد listener ها خیلی کم می شود و حافظه کم تری مصرف می شود.
- اگر بعدا المنت جدید به لیست اضافه شود، خود به خود رویدادش هندل می شود چون والد دارد گوش می دهد.
برای جواب مصاحبه کافی است یک مثال مثل لیست todo بگویی که روی ul listener می گذاری و بر اساس event.target تشخیص می دهی کدام li کلیک شده است.
سوال ۱۷
strict mode در جاوااسکریپت چیست
وقتی بالای فایل یا تابع بنویسی "use strict" جاوااسکریپت را می بری توی یک حالت سخت گیرتر.
چند اثر مهمش:
- جلوی بعضی اشتباه های رایج را می گیرد، مثلا استفاده از متغیری که تعریف نشده.
- بعضی رفتارهای عجیب را حذف می کند.
- راه را برای بهینه سازی موتور جاوااسکریپت بازتر می کند.
از وقتی ماژول ها آمده اند، بیشتر کدهای مدرن به طور پیش فرض شبیه حالت strict رفتار می کنند.
سوال ۱۸
چطور خطاها را در جاوااسکریپت مدیریت می کنی
برای کدهای همزمان از try و catch استفاده می کنیم. داخل try کد را می نویسی و اگر خطایی رخ بدهد می افتد توی catch.
برای Promise ها دو راه رایج داری:
- استفاده از
thenوcatch - یا استفاده از
asyncوawaitهمراه باtryوcatch
نکته ای که مصاحبه کننده دوست دارد بشنود این است که بگویی خطا را یا لاگ می کنی، یا پیام مناسب به کاربر می دهی، یا سعی می کنی یک حالت fallback داشته باشی و فقط سایلنت از کنار خطا رد نمی شوی.
سوال ۱۹
ماژول در جاوااسکریپت چیست
ماژول یعنی این که کد را به چند فایل با مسئولیت های جدا تقسیم کنیم و هر کدام فقط آن چیزی را که لازم است صادر کند.
در دنیای مدرن، معمولا از سینتکس import و export استفاده می شود. مثلا در یک فایل می نویسی:
export function sum(a, b) { return a + b }
و در فایل دیگر:
import { sum } from "./math.js"
این کار چند مزیت دارد:
- کد تمیزتر و قابل نگهداری تر می شود.
- می شود راحت تر تست نوشت.
- وابستگی ها واضح تر هستند.
اگر اشاره کنی که در محیط های قدیمی تر از require و module.exports استفاده می شد، نشان می دهد تجربه بیشتری داری.
سوال ۲۰
چطور کد جاوااسکریپت تمیز و قابل نگهداری می نویسی
این سوال آخر معمولا بازتر است و مصاحبه کننده می خواهد طرز فکر تو را ببیند.
چیزهایی که بد نیست به آن ها اشاره کنی:
- استفاده از اسم های معنی دار برای متغیر و تابع
- شکستن توابع بزرگ به توابع کوچک تر با یک مسئولیت مشخص
- پرهیز از تکرار کد و استفاده از توابع کمکی و abstraction های مناسب
- نوشتن کد به صورت ماژولار و جدا کردن لایه منطق از لایه نمایش
- نوشتن تست های حداقل برای بخش های حساس
- استفاده مداوم از
===به جای==و رعایت الگوهای رایج در تیم
اگر جواب این سوال را با یک مثال کوتاه از تجربه خودت قاطی کنی، معمولا تاثیر خوبی می گذارد و نشان می دهد فقط حفظ نکرده ای، واقعا با جاوااسکریپت کار کرده ای.