دانلود ویدیو

 

درک بهتر Scope در جاوااسکریپت یکی از قسمت‌های مهم یادگیری این زبان برنامه نویسی است. مفهوم Scope به معنی میزان دسترسی به متغیرها در توابع، آبجکت‌ها و بلاک‌های کد است.

مزایای Scope

برای مزایای استفاده از Scope می‌توان به این موارد اشاره کرد:

امنیت. متغیرها و توابع فقط زمانی قابل دسترسی هستند که به آنها نیاز داریم.

کمتر شدن تداخل در Namespaceها. تداخل Namespace زمانی اتفاق می‌افتد که برای دو متغیر متفاوت از یک نام استفاده می‌کنیم. Scope در متغیرها کمک می‌کند که استفاده از متغیرهای سراسری کمتر شود. در نتیجه برای تعریف نام متغیرها آزادی عمل بیشتری خواهیم داشت.

قابلیت استفاده مجدد از کدها. استفاده صحیح از متغیرهای محلی باعث توسعه ساده‌تر و قابلیت استفاده مجدد می‌شود.

انواع Scope

به طور کلی در زبان برنامه نویسی جاوااسکریپت دو نوع Scope داریم. Scopeهای سراسری و محلی. همین طور در این مطلب و ویدیوی آموزشی به طور دقیق Lexical Scope و Block Scope را نیز بررسی خواهیم کرد.

Scopeهای سراسری

زمانی که توسعه کدهای جاوااسکریپت را شروع می‌کنیم، در Scope یا Global Scope هستیم.

تمام کدهایی که در Scope سراسری توسعه می‌دهیم، مانند توابع، متغیرها و… در قسمت‌های مختلف برنامه قابل دسترسی هستند. چرخه حیات متغیرهای سراسری، کاملا وابسته به برنامه اصلی است. به این معنی که اگر برنامه بسته شود، متغیرها هم دیگر قابل استفاده نیستند.

با توجه به این موضوع، استفاده زیاد از متغیرهای سراسری کار منطقی‌ای نیست. تعریف بیش از اندازه متغیرهای سراسری باعث می‌شود کد برنامه کمتر قابلیت استفاده مجدد را داشته باشد. تا حد امکان این استفاده باید مدیریت شده باشد.

Scopeهای محلی

مقادیر محلی در برنامه فقط در جایی قابل دسترسی هستند که تعریف شده‌اند. ساده‌ترین راه تعریف یک Scope محلی، توسعه یک تابع است. در جاوااسکریپت هر تابعی که نوشته می‌شود، یک Scope محلی ایجاد می‌کند. داخل توابع هر متغیری که تعریف شود، به عنوان متغیر محلی در نظر گرفته خواهد شد. طبیعتا متغیرهای محلی فقط در همان Scope قابلیت دسترسی دارند.

این مثال را بررسی کنید:

 

var cat = 'Jerry';
console.log(cat); // Jerry
function localScopeExample(){
  var dog = 'Marley';
  console.log(cat); // Jerry
}
console.log(cat); // Jerry

 

در این مثال دو متغیر داریم. متغیر cat در Scope سراسری تعریف شده، پس در تمام قسمت‌های برنامه قابل دسترسی است. متغیر دیگر ما که dog است، در تابع localScopeExample تعریف شده. این متغیر را فقط در Scope محلی می‌توان استفاده کرد. اگر بیرون Scope آن را فراخوانی کنیم، برنامه با خطا مواجه خواهد شد.

اگر از متغیر dog در Scope سراسری استفاده کنیم، خطای Uncaught ReferenceError را خواهیم دید.

آخرین نکته در استفاده از Scopeهای محلی. این متغیرهای به صورت محلی در توابع تعریف شده‌اند. در نتیجه می‌توانیم از یک نام برای تعریف متغیرهای محلی در توابع مختلف استفاده کنیم.

 

function func1(){
  var dog = 'Marley';
  console.log(dog); // Marley
}
function func2(){
  var dog = 'Shasta';
  console.log(dog); // Shasta
}

 

بررسی Lexical Scope

Lexical Scope یا Static Scope به معنی توانایی دسترسی تابع داخلی به مقادیر یک تابع اصلی است. این مثال را بررسی کنید:

 

// *GLOBAL*
var dog = 'Lewis';
function outerFunc(){
  // *SCOPE 1*
  var cat = 'Jerry';
  function innerFunc(){
    // *SCOPE 2*
    console.log(cat); // Jerry
    console.log(dog); // Lewis
  }
}

 

در این کد تابع outerFunc به عنوان مقدار Scope سراسری تعریف شده. همین طور تابع innerFunc در داخل Scope تابع outerFunc استفاده شده. به خاطر مفهوم Lexical Scope تمام قسمت‌های Scope2 دسترسی به متغیرها در Scope1 را دارند.

تعریف مقادیر با استفاده از let و const

تا اینجا برای تعریف تمام متغیرها از دستور var استفاده کردیم. زمانی که از دستور var استفاده می‌کنیم، تنها توابع به عنوان یک Scope در نظر گرفته می‌شوند. اما Block Scopeهای دیگر مانند دستورات if ،for و while تاثیری بر روی var ندارند.

دستورات let و const در نسخه‌های جدید جاوااسکریپت ارایه شدند. تعریف مقادیر با این دستورات باعث می‌شود تا تمام Blockها به عنوان یک Scope در نظر گرفته شوند.

 

let x = 1;
{
  let x = 2;
  console.log(x); // 2
}
console.log(x); // 1

 

همین طور که مشاهده می‌کنید، استفاده از bracket باعث شده تا بتوانیم متغیر محلی داشته باشیم. با این که به نظر می‌رسد ما فقط یک متغیر x داریم، اما اینطور نیست. یکی از متغیرها با مقدار ۱ به عنوان متغیر سراسری تعریف شده. متغیر دیگر با مقدار ۲ یک متغیر محلی است.

جاوااسکریپت در زمان تفسیر، ابتدا متغیرهای داخلی را پردازش می‌کند. اگر متغیری را پیدا نکند، به ترتیب Blockهای بیرونی را پردازش خواهد کرد.

دقیقا همین موضوع برای سایر Block Scopeها مانند if ،for و while نیز وجود دارد.

 

let x = 1;
if (x !== 2) {
  let x = 2;
  console.log(x); // 2
}
console.log(x); // 1

 

توجه داشته باشید که شما نمی‌توانید متغیرهای هم نام را در یک Block مشخص تعریف و استفاده کنید.

 

{
  let x = 1;
  let x = 2;
}
Uncaught SyntaxError: Identifier 'x' has already been declared

 

امیدواریم که این مقاله برای شما مفید بوده باشد. برای دیدن ویدیوهای آموزشی یک قسمتی فرانت کست، می‌توانید کانال یوتوب فرانت کست را دنبال کنید.