آموزش جاوا اسکریپت – جلسه ۲۵ – سوالات رایج در مصاحبه

دوستان گرامی سلام. با جلسه بیست و پنجم از آموزش جامع جاوااسکریپت در خدمت شما هستم. در جلسه قبل (بیست و چهارم) بطور کامل با کوکی (cookie) در زبان برنامه نویسی جاوااسکریپت آشنا شدیم و نحوه خواندن کوکی و نوشتن در آن را توسط document.cookie (و همچنین getCookie و setCookie) بررسی کردیم. در این جلسه می خواهیم چند سوال رایج javascript را که در مصاحبه های استخدامی شرکت ها مطرح می شوند را بهمراه پاسخ تشریحی بررسی کنیم.
اگر شما در زمینه توسعه فرانت اند (Frontend Development) فعالیت دارید و در مصاحبه های استخدامی شرکت ها حضور داشته اید حتما برایتان پیش آمده که یک سری سوالات جاوا اسکریپتی مفهومی و بنیادی از شما پرسیده می شود.
ما در این مقاله سعی کردیم سوالات رایج javascript در جلسات مصاحبه استخدام شرکت ها را بهمراه پاسخ ارائه دهیم تا شما عزیزان بتوانید با دانش بیشتر از پس سوالات فرد مصاحبه کننده بر بیایید.
دانلود کتاب “سوالات تستی جاوا اسکریپت با پاسخ های کاملا تشریحی“
♦ شباهت های بین undefined و null؟
هر دوی آنها به نسخه 7 جاوا اسکریپت تعلق دارند و از انواع اولیه یا primitive هستند. انواع primitive به شکل زیر هستند:
let primitiveTypes = ['string','number','null','undefined','boolean','symbol', 'bigint'];
هر دوی آنها مقادیر falsy هستند. یعنی وقتی بعنوان مقدار بولین مورد ارزیابی قرار می گیرند برابر false خواهند بود:
console.log(!!null); //logs false console.log(!!undefined); //logs false console.log(Boolean(null)); //logs false console.log(Boolean(undefined)); //logs false
♦ تفاوت null و undefined؟
- Undefined: مقدار پیش فرض یک متغیر است که هنوز هیچ مقداری برای آن تعریف نشده است. یا تابعی است که هیچ مقداری را بر نمی گرداند. در واقع return ندارد. به 3 مقدار زیر دقت کنید:
let _thisIsUndefined; const doNothing = () => {}; const someObj = { a : "ay", b : "bee", c : "si" }; console.log(_thisIsUndefined); //logs undefined console.log(doNothing()); //logs undefined console.log(someObj["d"]); //logs undefined
- Null: یک مقدار است که بیانگر هیچ مقداری نیست! و هیچ مقداری ندارد. Null مقداریست که صراحتا می توان به یک متغیر نسبت داد. به مثال زیر توجه کنید:
fs.readFile('path/to/file', (e,data) => { console.log(e); //it logs null when no error occurred if(e){ console.log(e); } console.log(data); });
اگر بخواهیم null را با undefined مقایسه کنیم:
- با عملگر مقایسه ای == برابر true می شود.
- با عملگر مقایسه ای === برابر false می شود.
console.log(null == undefined); // logs true console.log(null === undefined); // logs false
♦ تفاوت بین preventDefault و event.stopPropagation
متد preventDefault مانع از اجرای رفتار پیش فرض در یک المان می شود. مثلا اگر در یک form تعریف شود از ثبت (submit) فرم جلوگیری می شود. اگر در یک تگ لینک استفاده شود از جابجایی یا navigate جلوگیری می کند. در حالیکه متد stopPropagation باعث می شود رویدادهای واقع در فازهای capturing و bubbling اجرا نشوند.
♦ event.target چیست؟
event.target بیانگر المانی است که یک رویداد بر روی آن اجرا شده است. مثلا کلیک. مثال:
کد html:
<div onclick="clickFunc(event)" style="text-align: center;margin:15px; border:1px solid red;border-radius:3px;"> <div style="margin: 25px; border:1px solid royalblue;border-radius:3px;"> <div style="margin:25px;border:1px solid skyblue;border-radius:3px;"> <button style="margin:10px"> Button </button> </div> </div> </div>
کد js:
function clickFunc(event) { console.log(event.target); }
در این مثال event.target به المان div که رویداد click در آن رخ داده است برمی گردد.
♦ تفاوت بین == و === چیست؟
فرق عملگر == (abstract equality) با عملگر === (strict equality) اینست که == فقط مقدار (value) ابتدا دو عملوند را هم نوع می کند (type عملوند دوم را به type عملوند اول تبدیل می کند) و سپس با یکدیگر مقایسه می کند اما === هم مقدار و هم نوع (type) آنها را مقایسه می کند. بیایید یک مثال بزنیم:
فرض کنید می خواهیم x == y را بررسی کنیم:
# | x | y | x == y |
1 | 5 | 5 | true |
2 | 1 | ‘1’ | true |
3 | null | undefined | true |
4 | 0 | false | true |
5 | ‘1,2’ | [1,2] | true |
6 | ‘[object Object]’ | {} | true |
مشاهده می کنید که خروجی تمام موارد فوق true است.
در خط اول: هم نوع متغیرها یکسان است و هم مقدار آنها. در خط دوم: متغیر y به عدد تبدیل می شود و با x مقایسه می شود. در خط سوم: نوع متغیرها یکسان نیست اما مقدار آنها برابر است و خروجی true است. در خط چهارم: متغیر y از بولین به عدد تبدیل می شود که برابر 0 می شود. در خط پنجم: متغیر دوم به رشته تبدیل می شود و سپس مقایسه صورت می گیرد. در خط ششم: آبجکت در متغیر دوم به رشته تبدیل می شود (توسط متد toString) سپس عملگر تساوی یعنی == اجرا می شود.
نکته: اگر بجای عملگر == از === یعنی سه تساوی استفاده می کردیم، به غیر از مورد اول، خروجی بقیه موارد false خواهد شد. زیرا === ابتدا نوع دو عملوند را با هم مقایسه می کند. اگر هم نوع بودند به سراغ مقایسه مقدار آنها می رود.
♦ کار عملگر !! چیست؟
عملگر Not دوتایی یا !! مقدار سمت راست خودش را به بولین (boolean) تبدیل می کند. به مثال های زیر توجه کنید:
console.log(!!null); //logs false console.log(!!undefined); //logs false console.log(!!''); //logs false console.log(!!0); //logs false console.log(!!NaN); //logs false console.log(!!' '); //logs true console.log(!!{}); //logs true console.log(!![]); //logs true console.log(!!1); //logs true console.log(!![].length); //logs false
♦ چگونه می توان در یک خط کد، چندین عملگر را روی یک عملوند اجرا کرد؟
بدین منظور می توان از ویرگول یا , استفاده کرد. عملگرها را از سمت چپ به راست روی عملوند اجرا می کند. در مثال زیر خروجی برابر 27 خواهد بود:
let x = 5; x = (x++ , x = addFive(x), x *= 2, x -= 5, x += 10); function addFive(num) { return num + 5; }
♦ Hoisting چیست؟
به حرکت متغیرها و توابع به سمت اسکوپ بالاتر از اسکوپ فعلی hoisting گفته می شود. برای فهم Hoisting باید ابتدا “زمینه اجرا” یا execution context را بفهمید. زمینه اجرا به محیط کد جاری و فعال گفته می شود. Execution Context دو فاز دارد: کامپایل (compilation) و اجرا (execution).
فاز کامپایل: در فاز compilation تمام توابع تعریف شده به بالای scope خودشان منتقل می شوند. به این منظور که بعدا بتوانیم تمام متغیرهایی که با کلمه var تعریف شده اند را بگیریم و به آنها مقدار پیش فرض undefined نسبت دهیم.
فاز اجرا: در فاز execution مقادیر مربوطه به متغیرها نسبت داده می شوند و توابع نیز اجرا می شوند.
نکته: فقط توابعی که به صورت function declaration تعریف شده اند و متغیرهایی که با var تعریف شده اند hoist می شوند و نه arrow function ها و function expression ها و متغیرهایی که با let و const تعریف شده اند.
برای روشن شدن قضیه به کد زیر که در global scope تعریف شده است دقت کنید:
console.log(y); y = 1; console.log(y); console.log(greet("Mark")); function greet(name){ return 'Hello ' + name + '!'; } var y;
خروجی کد فوق ابتدا undefined سپس 1 و در نهایت Hello Mark! خواهد بود. فاز کامپایل کد مذکور به صورت زیر می باشد:
function greet(name) { return 'Hello ' + name + '!'; } var y; //implicit "undefined" assignment //waiting for "compilation" phase to finish
و فاز اجرا نیز بدین شکل:
//then start "execution" phase console.log(y); y = 1; console.log(y); console.log(greet("Mark"));
در واقع در فاز اجرا توابع اجرا می شوند و متغیرها نیز مقداردهی می شوند.
♦ Scope چیست و انواع اسکوپ کدامند؟
اسکوپ در جاوا اسکریپت ناحیه ای است که می توان دسترسی معتبر و با مجوز به متغیرها یا توابع داشت. در جاوا اسکریپت 3 نوع scope داریم:
- Global Scope: توابع و متغیرهایی که در اسکوپ گلوبال تعریف می شوند از تمام جاهای برنامه قابل دسترسی هستند. بعنوان مثال:
//global namespace var g = "global"; function globalFunc(){ function innerFunc(){ console.log(g); // can access "g" because "g" is a global variable } innerFunc(); }
- Function Scope: توابع، متغیرها و پارامترهایی که درون بدنه یک تابع تعریف می شوند فقط در همان تابع قابل دسترسی هستند و از خارج از آن نمی توان دسترسی داشت. بعنوان مثال:
function myFavoriteFunc(a) { if (true) { var b = "Hello " + a; } return b; } myFavoriteFunc("World"); console.log(a); // Throws a ReferenceError "a" is not defined console.log(b); // does not continue here
- Block Scope: متغیرهایی که توسط let و const تعریف می شوند فقط در همان بلاک ({}) قابل دسترسی و شناخته شده هستند. بعنوان مثال:
function testBlock(){ if(true){ let z = 5; } return z; } testBlock(); // Throws a ReferenceError "z" is not defined
نکته: قانون اسکوپ ها بدین شکل است که از نزدیک ترین scope بدنبال متغیر یا تابع فراخوانی شده می گردد. اگر یافت نشد به اسکوپ بالاتر مراجعه می کند و بهمین ترتیب تا اسکوپ global بدنبال متغیر یا متد موردنظر می گردد و اگر پیدا نکند خطا رخ خواهد داد. بعنوان مثال:
/* Scope Chain Inside inner function perspective inner's scope -> outer's scope -> global's scope */ //Global Scope var variable1 = "Comrades"; var variable2 = "Sayonara"; function outer(){ //outer's scope var variable1 = "World"; function inner(){ //inner's scope var variable2 = "Hello"; console.log(variable2 + " " + variable1); } inner(); } outer(); // logs Hello World // because (variable2 = "Hello") and (variable1 = "World") are the nearest // variables inside inner's scope.
♦ Closure چیست؟
مبحث closureها در جاوا اسکریپت یکی از سخت ترین سوالات می باشد. بطور کلی closure قابلیت یک تابع است در به خاطر داشتن رفرنس متغیرها و پارامترها در اسکوپ جاری، اسکوپ والد، اسکوپ والد والد و… تا اسکوپ global
با ذکر یک مثال بهتر می توان closure را توضیح داد:
//Global's Scope var globalVar = "abc"; function a(){ //testClosures's Scope console.log(globalVar); } a(); //logs "abc" /* Scope Chain Inside a function perspective a's scope -> global's scope */
♦ مقادیر false در جاوا اسکریپت کدامند؟
falsy values به مقادیری گفته می شوند که اگر به بولین تبدیل شوند برابر false خواهند شد.
const falsyValues = ['', 0, null, undefined, NaN, false];
♦ چگونه می توان چک کرد که آیا یک مقدار false است یا true؟
با استفاده از عملگر !! (Double NOT)
♦ دستور use strict چیست؟
Use strict یکی از ویژگی های ES5 است که باعث می شود اسکریپت ما در مد strict کار کند (حالت سختگیرانه) و باگ های احتمالی برنامه ما افزایش خواهند یافت. Strict mode امکانات زیر را برای برنامه نویس فراهم می کند:
- نسبت دادن یک مقدار یا دسترسی به مقدار یک متغیری که تعریف نشده است:
function returnY(){ "use strict"; y = 123; return y; }
- نسبت دادن یک مقدار به متغیری که فقط خواندنی یا read-only است:
"use strict"; var NaN = NaN; var undefined = undefined; var Infinity = "and beyond";
- پاک کردن یک property که غیرقابل حذف است:
"use strict"; const obj = {}; Object.defineProperty(obj, 'x', { value : '1' }); delete obj.x;
- تعریف نام تکراری برای پارامترهای یک تابع:
"use strict"; function someFunc(a, b, b, c){ }
- ایجاد یک متغیر توسط eval function:
"use strict"; eval("var x = 1;"); console.log(x); //Throws a Reference Error x is not defined
- مقدار پیش فرض this برابر undefined می باشد:
"use strict"; function showMeThis(){ return this; } showMeThis(); //returns undefined
سوالات رایج جاوا اسکریپت در مصاحبه های استخدامی شرکت ها در اینجا به پایان می رسد اما این مقاله بطور مرتب بروزرسانی خواهد شد. در مقاله بعد (جلسه 26) با مبحث تست نویسی (Testing) و ابزارهای آن در زبان برنامه نویسی جاوا اسکریپت همراه شما خواهیم بود.
دانلود کتاب “سوالات تستی جاوا اسکریپت با پاسخ های کاملا تشریحی“
مطالب زیر را حتما مطالعه کنید
5 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
البته ببخشید خطای تایپی داشتم، Closure
🙂
خیلی خوب بود و عالی، فقط مثال قسمت clouser رو فکر میکنم اگه زنجیره بیشتری داشت بهتر مفهومش رو نشون میداد، سپاس فراوان
میدونستین use strict رو اشتباه توضیح دادین، کاملا برعکس گفتین
ممنون از اطلاع رسانی شما. بررسی می شود.