Scope در جاوا اسکریپت چیست؟ – توضیح به زبان ساده + مثال و کد

۸۱۷ بازدید
آخرین به‌روزرسانی: ۰۷ تیر ۱۴۰۲
زمان مطالعه: ۷ دقیقه
Scope در جاوا اسکریپت چیست؟ – توضیح به زبان ساده + مثال و کد

Scope در جاوا اسکریپت مفهومی اساسی است که دسترسی یا قابل مشاهده بودن متغیرها، اشیا و توابع را تعیین می‌کند. در واقع به وسیله Scope در JavaScript می‌توان محدوده‌ای از کدها را تعیین کرد که در آن به متغیر یا تابع دسترسی داریم. ۲ نوع اصلی Scope در زبان برنامه نویسی جاوا اسکریپت وجود دارند که هر کدام از آن‌ها کاربردهای خاص خودشان را دارند. در این مطلب از «مجله فرادرس»، بحث Scope در جاوا اسکریپت و انواع آن به همراه مثال‌هایی با زبان ساده آموزش داده خواهد شد.

997696

Scope در جاوا اسکریپت چیست؟

در محیط جاوا اسکریپت، «Scope» به معنای دامنه (محدوده) کدهای کاربر است. این دامنه به عنوان نوعی تعیین کننده دسترسی به توابع و متغیرها در جاوا اسکریپت عمل می‌کند. به عبارت ساده‌تر، تصمیم کاربر در مورد مکان اعلان تابع یا متغیر در جاوا اسکریپت، متعاقباً بر دسترسی آن تأثیر می‌گذارد. از این رو، وقتی متغیری در تابعی اعلان می‌شود، تنها در محدوده آن تابع قابل دسترسی است.

  • نکته: منظور از کلمات «محدوده» و «دامنه» در این بحث یکسان است. همچنین کلمات «محدوده سراسری» و «محدوده جهانی» نیز مترادف هستند.

انواع Scope در جاوا اسکریپت

اصطلاح Scope در جاوا اسکریپت به معنای دسترسی به متغیرها و توابع در بخش‌های خاصی از کدها است. در دنیای برنامه نویسی جاوا اسکریپت، محدوده متغیرها به چند دسته زیر تقسیم می‌شود:

  • «محدوده سراسری» (Global Scope)
  • «اسکوپ محلی» (Local Scope)
  • «محدوده تابع» (Function Scope)
  • «اسکوپ بلوک» (Block Scope)
  • «محدوده واژگانی» (Lexical Scope)

در ادامه این آموزش Scope در جاوا اسکریپت، تمامی محدوده‌های نام برده به همراه مثال آموزش داده خواهند شد.

انواع Scope در جاوا اسکریپت

محدوده سراسری در جاوا اسکریپت چیست؟

متغیرهایی که در ابتدای برنامه اعلان می‌شوند یا آن‌هایی که در تابعی محصور نشده‌اند، در «محدوده سراسری | جهانی» (Global Scope) قرار می‌گیرند. اصطلاح Scope در جاوا اسکریپت نشان می‌دهد که آیا متغیر یا تابع می‌تواند از قسمت‌های مختلف کدها قابل دسترسی باشد یا خیر.

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

1var companion = 'dog';
2function displayCompanion() {
3  console.log(companion); // outputs 'dog' in the console
4}

در قطعه کد داده شده، متغیری به نام companion تعریف شده است. همچنین مقدار dog به این متغیر اختصاص دارد. همچنین تابعی به نام displayCompanion اعلان شده که مقدار companionرا در کنسول ثبت می‌کند. از آنجایی که companionنوعی متغیر سراسری است، می‌توان در تابعdisplayCompanionبه آن دسترسی ایجاد کرد. به طور مشابه، می‌توان به companionدر خارج از تابع دسترسی داشت که خروجی آن به صورت زیر خواهد بود.

1console.log(companion); // outputs 'dog' in the console

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

1var companion = 'cat';    
2function displayCompanion() {
3  console.log(companion); // outputs 'cat' in the console
4}
5console.log(otherCompanion); // outputs 'undefined' in the console

در کدهای بالا، متغیری به نامcompanionوجود دارد که مقدار cat به آن اختصاص داده شده است و تابعی به نام displayCompanionوجود دارد که companionرا ثبت می‌کند. با این حال، otherCompanion در محدوده جهانی تعریف نشده و بنابراین دسترسی آن خارج از تابع displayCompanionتعریف نشده خواهد بود.

1console.log(otherCompanion); // outputs 'undefined' in the console

چند مثال از Global Scope در جاوا اسکریپت

در جاوا اسکریپت، زمانی که متغیری در ابتدای «اسکریپت» (Script) یا خارج از هر تابعی اعلان می‌شود، به عنوان متغیر سراسری در نظر گرفته خواهد شد، به این معنی که می‌توان به آن دسترسی داشت و در هر جایی از برنامه از آن استفاده کرد.

در ادامه این مطلب از مجله فرادرس چند مثال دیگر برای این نوع محدوده در جاوا اسکریپت آورده شده که مثال اول به صورت زیر است:

1// Script to print a message
2let greeting = "hello";
3
4function sayHello () {
5    console.log(greeting);
6}
7
8sayHello(); // Outputs: hello

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

1// Script to demonstrate change in global variable
2let greeting = "hello";
3
4function changeGreeting() {
5    greeting = 3;
6}
7
8// before invoking the function
9console.log(greeting);
10
11// after invoking the function
12changeGreeting();
13console.log(greeting); // Outputs: 3

در کدهای بالا، greetingنوعی متغیر سراسری به حساب می‌آید که به صورت hello مقداردهی شده است. با این حال، در تابع changeGreeting ، مقدار آن به 3 تغییر می‌کند و این تغییر زمانی که greetingپس از آن ثبت می‌شود، منعکس خواهد شد.

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

1function sayHello() {
2    greeting = "hello"
3}
4
5sayHello();
6
7console.log(greeting); // Outputs: hello

در این مورد، greetingنوعی متغیر جهانی محسوب می‌شود، حتی اگر به صراحت اعلان نشده باشد. اگر متغیر با let greeting = "hello" اعلان شود، برنامه خطا ایجاد می‌کند. باید به این نکته توجه داشت که جاوا اسکریپت نوعی «حالت سخت گیرانه» (Strict Mode) ارائه می‌دهد که در آن متغیر نمی‌تواند بدون اعلان اولیه استفاده شود.

محدوده محلی در جاوا اسکریپت چیست ؟

مفهوم «محدوده یا دامنه محلی» (Local Scope) به متغیر یا تابعی اشاره دارد که فقط در بلوک کد فعلی آن قابل دسترسی است.

می‌توان با استفاده از {} محدوده محلی ایجاد کرد که مثال زیر این مفهوم را بیان می‌کند:

1{
2  var companion = 'cat';
3}
4console.log(companion); // outputs 'undefined' in the console

در قطعه بالا، companion مقدار cat را با محدوده محلی ایجاد شده به وسیله {}اختصاص داده است. با این حال، خارج از{}نمی‌توان به companionدسترسی پیدا کرد، اما در همان محدوده، قابل دسترسی خواهد بود.

1console.log(companion); // outputs 'cat' in the console

مثالی برای Scope محلی در جاوا اسکریپت

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

1// Demonstrating the local scope of a variable
2let a = "hello";
3
4function greet() {
5let b = "World"
6console.log(a + b);
7}
8
9greet();
10console.log(a + b); // error
11Execute Code
12//Output
13
14//helloWorld
15//Uncaught ReferenceError: b is not defined 

در قطعه کد بالا، متغیر a نوعی متغیر سراسری در نظر گرفته می‌شود، در حالی که متغیر b متغیری محلی است. دسترسی به متغیر bبه تابع greet محدود شده است. در نتیجه، زمانی که تلاشی برای دسترسی به متغیر bخارج از تابع آن انجام می‌شود، خطایی ایجاد خواهد شد.

محدوده محلی در جاوا اسکریپت
  • نکته: همانطور که در تصویر بالا معلوم است، محدوده محلی، خود می‌تواند شامل ۳ نوع محدوه تابع، محدوه بلوک و محدوده «ماژول» (Module) باشد.

محدوه تابع در جاوا اسکریپت چیست؟

یکی دیگر از انواع Scope در جاوا اسکریپت، «محدوده تابع» (Function Scope) است که محدوده محلی را با تفاوتی کوچک منعکس می‌کند. در این نوع محدوده، متغیرها و توابعِ تعریف شده در داخل تابع را نمی‌توان به صورت سراسری در دسترس قرار داد.

مثال زیر برای درک این نوع محدوده در جاوا اسکریپت مهم است.

1function displayCompanion() {
2  var companion = 'cat';
3  console.log(companion); // outputs 'cat' in the console
4}

در مثال فوق، companionدر displayCompanion تعریف شده است، از این رو فقط در داخل تابع قابل دسترسی خواهد بود و خارج از تابع، غیر قابل دسترسی است.

1console.log(companion); // outputs 'undefined' in the console

محدوده بلوک در جاوا اسکریپت

نوعی دیگری از Scope در جاوا اسکریپت، نوع بلوکی آن یا «محدوده بلوکی» (Block Scope) است. محدوده بلوک کاربر را قادر می‌سازد تا متغیرها و توابع را منحصراً برای بلوک کد خاصی (هر بخش محصور در {} ) تعریف کند.

می‌توان با استفاده از کلمات کلیدی let یا const محدوده بلوکی ایجاد کرد. مثال زیر برای درک این مفهوم ضروری است.

1let companion = 'cat';
2if (true) {
3  let companion = 'dog';
4  console.log(companion); // outputs 'dog' in the console
5}
6console.log(companion); // outputs 'cat' in the console

در قطعه بالا، از let برای تعریف companionدر عبارت if استفاده شده و نوعی محدوده بلوک ایجاد شده است. خارج از بلوک کد سراسری، companionغیر قابل دسترسی باقی می‌ماند:

1console.log(companion); // outputs 'undefined' in the console
  • نکته: برای متغیرهای Block Scope در جاوا اسکریپت، محدوده‌ای ایجاد نمی‌شود.

مثال Block Scope در جاوا اسکریپت

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

مثال زیر برای نشان دادن مفهوم محدوده بلوکی برای درک بهتر این موضوع اهمیت زیادی دارد.

1// A program demonstrating the block scope notion
2// Global variable
3let a = 'Hello';
4
5function greet() {
6
7javascript
8Copy code
9// Local variable
10let b = 'World';
11
12console.log(a + ' ' + b);
13
14if (b == 'World') {
15
16    // Block-scoped variable
17    let c = 'hello';
18
19    console.log(a + ' ' + b + ' ' + c);
20}
21
22// Variable c isn't accessible here
23console.log(a + ' ' + b + ' ' + c);
24}
25
26greet();

خروجی کدهای بالا به صورت زیر است:

Hello World
Hello World hello
Uncaught ReferenceError: c is not defined
تشریح کد بالا به صورت زیر است:
  • a متغیری سراسری بوده و در هر جایی از برنامه قابل دسترسی است.
  • b متغیری محلی بوده که فقط در داخل تابع greet قابل دسترسی است.
  • c متغیری با محدوده بلوک بوده که فقط در بلوک دستورifقابل دسترسی است.

در برنامه فوق، ۲ اجرای اول console.log()‎ بدون مشکل اجرا می‌شوند. با این حال، در سومین فراخوانی console.log()‎سعی می‌شود به متغیر cبا محدوده بلوک در خارج از بلوک آن دسترسی پیدا شود که منجر به خطا خواهد شد.

Block Scope در جاوا اسکریپت

توجه به این نکته مهم است که در جاوا اسکریپت، در حالی که var دارای محدوده تابعی است، let محدوده بلوکی دارد. اگر let c = 'hello' با var c = 'hello' در عبارت ifجایگزین شود، در نتیجه برنامه با موفقیت اجرا خواهد شد. زیرا cبه عنوان نوعی متغیر محلی در نظر گرفته می‌شود.

محدوده واژگانی در جاوا اسکریپت

یکی دیگر از انواع Scope در جاوا اسکریپت، «محدوده واژگانی» (Lexical Scope) است. محدوده یا دامنه واژگانی، که همچنین به عنوان «محدوده ایستا» (Static Scope) یا «محدوده کامپایل-زمان» (Compile-Time Scope) نیز شناخته می‌شود، مفهوم پیچیده‌تری است.

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

1var companion = 'cat';
2function displayCompanion() {
3  console.log(companion); // outputs 'cat' in the console
4}

در مثال فوق، companionدر محدوده سراسری تعریف شده و در displayCompanion قابل دسترسی است. اما در بلوک کد، companionقابل دسترسی نیست:

1if (true) {
2  var companion = 'dog';
3  console.log(companion); // outputs 'dog' in the console
4}
5console.log(companion); // outputs 'undefined' in the console

در قطعه کد فوق، companionبا استفاده از "varدر داخل عبارت ifتعریف شده و خارج از بلوک کد غیر قابل دسترسی است:

1console.log(companion); // outputs 'undefined' in the console

سخن پایانی

مفهوم scope در جاوا اسکریپت بحثی اساسی به حساب می‌آید که دسترسی به متغیرها و توابع را دیکته می‌کند. قوانین scope به طور یکنواخت برای متغیرهای const و let اعمال می‌شود، خواه آن‌ها در بلوکی از کدها، تابع یا ماژولی خاص قرار بگیرند. در مقابل، متغیرهای var تنها زمانی از این قوانین پیروی می‌کنند که در تابع یا ماژولی قرار گیرند.

استفاده مناسب از Scope در جاوا اسکریپت مزایای مختلفی از جمله افزایش امنیت و پتانسیل استفاده مجدد از کدها را ارائه می‌دهد. در این مطلب از مجله فرادرس بحث Scope در Javascript به صورت نسبتاً کامل بحث شد و انواع این Scope‌ها به همراه مثال‌هایی با زبان ساده بحث شدند.

بر اساس رای ۲ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
Blog.HubSpotProgramiz
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *