موضوعات اصلی جاوا اسکریپت که باید شماره 1 را بدانید (حوزه، بالا بردن، منطقه مرده زمانی)

آیا تا به حال احساس کرده اید که کد جاوا اسکریپت شما کارهای عجیب و غریبی انجام می دهد، یا متوجه نشده اید که چرا یک متغیر تعریف نشده دارید؟ و مطمئن شده اید که مقداردهی اولیه را به این متغیر اختصاص داده اید؟
خوب، در واقعیت چیز عجیبی وجود ندارد، ما فقط برخی از اصول اولیه و آسان را فراموش می کنیم یا نمی دانیم که در زیر نشان خواهم داد تا دوباره آنها را فراموش نکنید.
Scope، Hoisting و Temporal Dead Zone که این پست در مورد آن است
چیست؟
دامنه دسترسی به متغیرها را در هر قسمت از کد ما تعیین می کند.
در جاوا اسکریپت انواع مختلفی از Scope ها داریم:
دامنه جهانی
زمانی که متغیری خارج از یک تابع یا بلوک اعلان شود، در محدوده جهانی گفته می شود. ما میتوانیم از هر قسمتی از کدمان، چه در داخل یا خارج از یک تابع، به این نوع متغیرها دسترسی داشته باشیم.
var name = "Leonardo";
// The code written in this part will be able to access name.
function myFunction() {
// The code written in this part will also be able to
access name.
}
محدوده محلی
متغیرهایی که در داخل یک تابع تعریف می کنیم، متغیرهای محلی هستند، یعنی در محدوده محلی یافت می شوند. این بدان معنی است که این نوع متغیرها فقط در تابعی که ما آنها را اعلام کرده ایم زندگی می کنند و اگر سعی کنیم خارج از آن به آنها دسترسی پیدا کنیم، این متغیرها تعریف نمی شوند.
// The code written in this part will NOT be able to access the variable name.
function myFunction() {
var name = "Leonardo";
// The code written here can access to the variable.
}
Block Scope
برخلاف محدوده محلی، این محدوده محدود به بلوک کدی است که متغیر در آن تعریف شده است. از آنجایی که ECMAScript 6 ما کلمات کلیدی let و const را داریم که به ما امکان می دهد یک محدوده بلوکی داشته باشیم، این بدان معنی است که متغیرها فقط در بلوک کد مربوطه زندگی می کنند.
if (true) {
// this if block does not create a scope
// variable name is global because of the use of the 'var' keyword
var name="Leonardo";
// country is in the local scope because of the use of the 'let' keyword
let country = 'Mexico';
// language is also a local scope because of the use of the 'const' keyword
const language="Javascript";
}
console.log(name); // prints 'Leonardo'
console.log(country); // Uncaught ReferenceError: country is not defined
console. log(language); // Uncaught ReferenceError: language is not defined
دامنه واژگانی
دامنه واژگانی به این معنی است که در یک گروه تو در تو از توابع، توابع داخلی به متغیرها و سایر منابع دامنه اصلی خود دسترسی دارند. این بدان معنی است که عملکردهای فرزند از نظر لغوی با زمینه اجرای والدینشان مرتبط است.
function myFunction() {
var name="Leonardo";
// we can't access language from here
function parent() {
// name is accessible from here.
// language is not accessible.
function child() {
// We can also access name from here.
var language="Javascript";
}
}
}
چیست؟
برای مثال، از نظر مفهومی، تعریف دقیقی از بالا بردن نشان میدهد که اعلانهای متغیر و تابع به صورت فیزیکی به ابتدای کد منتقل میشوند، اما در واقع اینطور نیست.
اتفاقی که می افتد این است که اعلان های متغیرها و توابع در مرحله کامپایل در حافظه تخصیص می یابند، اما دقیقا همان جایی که در کد نوشته اید باقی می مانند.
نمونه ای از بالا بردن با عملکرد
hello("Leo");
function hello(name) {
console.log("Hello " + name);
}
/*
Printed Result "Hello Leo"
*/
یکی از مزایای جاوا اسکریپت hoisting این است که به شما امکان می دهد از یک تابع قبل از اعلام آن در کد خود استفاده کنید.
همانطور که می بینید، با وجود اینکه ابتدا تابع موجود در کد را فراخوانی می کنیم، قبل از اینکه نوشته شود، کد همچنان کار می کند.
چیست؟
منطقه مرده زمانی (TDZ) ناحیه ای از یک بلوک است که در آن متغیر تا زمانی که کامپیوتر آن را به طور کامل با یک مقدار مقدار دهی اولیه کند، غیرقابل دسترسی است.
فرض کنید سعی می کنید قبل از مقداردهی اولیه به یک متغیر دسترسی پیدا کنید. در چنین حالتی، جاوا اسکریپت a را پرتاب می کند ReferenceError
.
بنابراین، برای جلوگیری از ایجاد چنین خطایی در جاوا اسکریپت، باید به یاد داشته باشید که به متغیرهای خود از خارج از منطقه مرده موقت دسترسی داشته باشید.
اما TDZ (منطقه مرده موقت) دقیقاً کجا شروع و به کجا ختم می شود؟
// TDZ start here
console.log(name); // returns ReferenceError because name TDZ are present
let name = "Leonardo" // TDZ ends
// TDZ not exist here
در اینجا نحوه دسترسی شما آمده است name
با موفقیت پس از مقداردهی اولیه کامل:
let name = "Leonardo"; // name TDZ ends here
console.log(name); // returns "Leonardo" because name TDZ does not exist here
تمام اصول منطقه مرده زمانی متغیرهای let برای const نیز اعمال می شود. با این حال، var متفاوت عمل می کند.
تفاوت اصلی بین منطقه مرده زمانی متغیر var، let و const زمانی است که TDZ آنها به پایان می رسد.
// name TDZ starts and ends here
console.log(name); // returns undefined because name TDZ does not exist here
var name = "Leonardo"; // name TDZ does not exist here
console.log(name); // returns "Leonardo" because name TDZ does not exist here
دستور console.log با موفقیت یک مقدار (تعریف نشده) را برگرداند زیرا جاوا اسکریپت به طور خودکار تعریف نشده را به یک متغیر hoisted اختصاص می دهد.
به عبارت دیگر، هنگامی که جاوا اسکریپت یک متغیر var را بالا می برد، به طور خودکار متغیر را با مقدار تعریف نشده مقداردهی اولیه می کند.
در مقابل، جاوا اسکریپت هر زمان که متغیر را بالا میبرد، یک متغیر let (یا const) را با هیچ مقدار مقداردهی اولیه نمیکند. در عوض، متغیر مرده و غیر قابل دسترس باقی می ماند.
بنابراین، TDZ یک متغیر let (یا const) زمانی پایان مییابد که جاوا اسکریپت به طور کامل آن را با مقدار مشخص شده در طی اعلان اولیه مقداردهی اولیه کند.
با این حال، TDZ یک متغیر var بلافاصله پس از بالا بردن آن به پایان می رسد، نه زمانی که متغیر به طور کامل با مقدار مشخص شده در طی اعلان اولیه مقداردهی اولیه شود.
نتیجه گیری
اینها مفاهیم اولیه ای هستند که بسیاری از ما از آنها بی اطلاع هستیم زیرا بدون اینکه نگاهی به نحوه کارکرد زبان بیندازیم برنامه نویسی را شروع می کنیم و مستقیماً به سراغ پرتاب کد می رویم، اما دانستن نحوه کار زبان و دانستن این مفاهیم اولیه ما را به توسعه دهندگان بهتری برای تولید تبدیل می کند. بهترین راه حل ها