Hoisting در جاوا اسکریپت – توضیح مفهوم به زبان ساده

۱۲۱۱ بازدید
آخرین به‌روزرسانی: ۰۷ شهریور ۱۴۰۲
زمان مطالعه: ۱۳ دقیقه
Hoisting در جاوا اسکریپت – توضیح مفهوم به زبان ساده

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

997696

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

تفاوت بین undefined و ReferenceError در جاوا اسکریپت

یکی از پیش‌نیازهای درک مفهوم Hoisting در جاوا اسکریپت، درک تمایز بین دو نوع خطای رایج در این زبان، یعنی «تعریف نشده» (undefined) و «خطای مرجع» (ReferenceError) است.

برای پرداختن به این موضوع توجه به مثال زیر در این رابطه اهمیت زیادی دارد.

1console.log(typeof variable);

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

فرق بین undefined و ReferenceError

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

1console.log(variable); // Output: ReferenceError: variable is not defined

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

hoisting در جاوا اسکریپت چیست

در جاوا اسکریپت، اگر تلاشی برای دسترسی به متغیری انجام شود که قبلاً اعلام نشده است، خطای مرجع ReferenceErrorایجاد خواهد شد. رفتار جاوا اسکریپت هنگام مدیریت متغیرها به دلیل وجود Hoisting پیچیده می‌شود. در بخش‌های آتی این مفهوم به صورت کامل بررسی می‌شود.

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

Hoisting در جاوا اسکریپت فرآیندی است که طی آن اعلان‌های متغیر و تابع در مرحله آماده‌سازی کد به بالای محدوده مربوطه خود منتقل می‌شوند. در این رابطه متغیرهای اعلان شده با کلمه کلیدی «Var» به بالای محدوده خود منتقل شده و با «Undefined» مقداردهی اولیه خواهند شد. از طرفی دیگر آن‌هایی که با استفاده از کلمات کلیدی «Let» و «Const» اعلان شوند تا زمانی که به طور صریح مقداری به آن‌ها اختصاص داده نشود، بدون مقدار اولیه باقی می‌مانند.

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

Hoisting در جاوا اسکریپت برای متغیرها

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

Hoisting در جاوا اسکریپت برای متغیرها

با این وجود، به دلیل قابلیت جاوا اسکریپت برای اعلان و مقداردهی اولیه متغیرها به طور هم‌زمان، روش رایج اعلان متغیر شامل الگوی زیر می‌شود:

1var a = 100;

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

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

1function hoist() {
2  a = 20;
3  var b = 100;
4}
5
6hoist();
7
8console.log(a); 
9/* 
10Accessible as a global variable outside hoist() function
11Output: 20
12*/
13
14console.log(b); 
15/*

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

متغیرها در ES5

برای بهتر روشن شدن قضیه Hoisting در جاوا اسکریپت در این بخش به بررسی نحوه تعریف متغیرها در جاوا اسکریپت «ES5» خواهیم پرداخت. محدوده متغیری که با استفاده از کلمه کلیدی varاعلان می‌شود، شامل زمینه فعلی اجرای آن است. این زمینه می‌تواند تابعی محصور کننده باشد. همچنین می‌تواند برای متغیرهایی که خارج از تابع اعلان شده‌اند، محدوده سراسری باشد.

Hoisting در متغیرهای سراسری

برای درک عمل Hoisting در متغیرهای سراسری توجه به مثال زیر در آغاز کار مهم است:

1console.log(hoist); // Output: undefined
2
3var hoist = 'The variable has been hoisted.';

در کد بالا در حالی که ممکن است به دلیل متغیر تعریف نشده انتظار خطای مرجع را داشته باشیم، خروجی در واقع undefinedاست. امکان دارد برای کاربر سؤال باشد که چرا این اتفاق می‌افتد؟ در این مورد می‌توان گفت که عمل Hoisting در جاوا اسکریپت اتفاق افتاده است و اساساً مثال فوق به صورت زیر تفسیر می‌شود.

1var hoist;
2
3console.log(hoist); // Output: undefined
4hoist = 'The variable has been hoisted.';

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

مردان در حال حمل کارتن

Hoisting برای متغیرهای محدوده تابع

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

1function hoist() {
2  console.log(message);
3  var message = 'Hoisting is all the rage!';
4}
5
6hoist();

مفسر جاوا اسکریپت کد بالا را به صورت زیر می‌بیند:

1function hoist() {
2  var message;
3  console.log(message);
4  message = 'Hoisting is all the rage!';
5}
6
7hoist(); // Output: undefined

همانطور که قابل مشاهده است، خروجی undefinedخواهد بود. اعلان متغیر var messageکه به محدوده تابع hoist()تعلق دارد، در بالای آن تابع قرار می‌گیرد. برای فرار از این دام، نوعی رویکرد محتاطانه این است که متغیر قبل از استفاده از آن اعلان و مقداردهی اولیه شود. مانند مثال زیر:

1function hoist() {
2  var message = 'Hoisting is all the rage!';
3  return message;
4}
5
6hoist(); // Output: Hoisting is all the rage!

حالت سخت گیرانه در جاوا اسکریپت چیست؟

به لطف نوعی ویژگی در نسخه ES5 جاوا اسکریپت که به عنوان «حالت سخت‌گیرانه» (Strict Mode) شناخته می‌شود، می‌توان هنگام اعلان متغیرها احتیاط بیشتری به خرج داد. با استفاده از این حالت سخت‌گیرانه کاربر با جاوا اسکریپت قابل تنظیم‌تری سروکار خواهد داشت و در این حالت جاوا اسکریپت اجازه استفاده از متغیرها را قبل از اعلان رسمی آن‌ها نمی‌دهد. Strict Mode در جاوا اسکریپت مزیت‌های زیادی دارد که از مهم‌ترین آن‌ها می‌توان موارد زیر را نام برد:

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

 نحوه فعال سازی حالت سخت گیرانه در جاوا اسکریپت

برای فعال کردن حالت سخت، دستورالعمل زیر باید در ابتدای فایل یا تابع مدنظر قرار بگیرد:

1'use strict';
2
3// OR
4"use strict";

توجه به مثال زیر در این رابطه بسیار مهم است:

1'use strict';
2
3console.log(hoist); // Output: ReferenceError: hoist is not defined
4hoist = 'Hoisted';

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

مردان در حال حمل پشته کدهای جاوا اسکریپت - hoisting در جاوا اسکریپت

متغیرها در ES6

«ECMAScript 6» که همچنین به عنوان «جاوا اسکریپت ES6» یا «ECMAScript 2015» شناخته می‌شود، جدیدترین استاندارد جاوا اسکریپت تا زمان نگارش این مقاله (مرداد ١٤٠٢ شمسی) است. ES6 تغییرات متعددی را در مقایسه با ES5 معرفی می‌کند و در میان این تغییرات نحوه اعلان و مقداردهی اولیه متغیرهای جاوا اسکریپت بسیار قابل‌توجه است که در ادامه به معرفی این ویژگی پرداخته خواهد شد.

کلمه کلیدی let در  جاوا اسکریپت ES6

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

1console.log(hoist); // Output: ReferenceError: hoist is not defined ...
2let hoist = 'The variable has been hoisted.';

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

1let hoist;
2
3console.log(hoist); // Output: undefined
4hoist = 'Hoisted';

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

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

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

1const PI = 3.142;
2
3PI = 22/7; // Attempting to reassign the value of PI
4
5console.log(PI); // Output: TypeError: Assignment to constant variable.

اما چگونه constاعلان متغیر را تغییر می‌دهد؟ توجه به مثال زیر در این رابطه مهم است:

1console.log(hoist); // Output: ReferenceError: hoist is not defined
2const hoist = 'The variable has been hoisted.';

مشابه سناریوی کلمه کلیدی let، به جای نتیجه undefined، مفسر با پرتاب صریح خطای مرجع از خطاها جلوگیری می‌کند. همچنین همین رفتار هنگام استفاده از constدر توابع حفظ می‌شود. مثال زیر این مفهوم را بیان می‌کند.

1function getCircumference(radius) {
2  console.log(circumference);
3  circumference = PI * radius * 2;
4  const PI = 22/7;
5}
6
7getCircumference(2); // Output: ReferenceError: circumference is not defined

جاوا اسکریپت ES6 با کلمه کلیدی constیک قدم فراتر می‌رود. اگر ثابتی قبل از اعلان و مقداردهی اولیه استفاده شود، مفسر خطا ایجاد می‌کند. همچنین رفتار constرا در سطح سراسری نیز می‌توان در مثال زیر دید.

1const PI;
2console.log(PI); // Ouput: SyntaxError: Missing initializer in const declaration
3PI=3.142;

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

دو مرد در حال روی هم قرار دادن بسته کدها

به عنوان نکته پایانی برای این بخش، تأکید بر این نکته مهم است که در واقع، در جاوا اسکریپت متغیرهای اعلان شده با استفاده از کلمات کلیدی letو constقابلیت Hoisting دارند. متغیرهای اعلان شده با letو constدر ابتدای اجرا بدون مقدار اولیه باقی می‌مانند، در حالی که متغیرهای اعلان شده با varبا مقدار undefinedمقداردهی اولیه می‌شوند.

Hoisting در جاوا اسکریپت برای توابع

توابع جاوا اسکریپت را می‌توان به طور کلی به دو نوع زیر دسته‌بندی کرد:

  • «اعلان تابع» (Function Declarations)
  • «عبارت تابع» (Function Expressions)

حال در ادامه به مفهوم Hoisting در جاوا اسکریپت برای توابع توضیحاتی در هر دو مورد ارائه خواهد شد.

اعلان تابع به صورت ساختاریافته و به طور کامل در بالای محدوده مربوطه خود قرار می‌گیرند. به همین دلیل است که جاوا اسکریپت ظاهراً به برنامه‌ نویس اجازه می‌دهد تا تابع را قبل از اعلان رسمی آن فراخوانی کند. توجه به مثال زیر در این رابطه بسیار اهمیت دارد:

1hoisted(); // Output: "This function has been hoisted."
2
3function hoisted() {
4  console.log('This function has been hoisted.');
5};

از سوی دیگر، عبارات تابع رفتار Hoisting را از خود نشان نمی‌دهد. مثال زیر در این رابطه مهم است:

1expression(); // Output: "TypeError: expression is not a function"
2
3var expression = function() {
4  console.log('Will this work?');
5};

اما این عمل برای ترکیب اعلان تابع و عبارت تابع به چه صورت است؟ در مثال زیر ترکیبی برای اعلان تابع و عبارت تابع آورده شده است:

1expression(); // Output: TypeError: expression is not a function
2
3var expression = function hoisting() {
4  console.log('Will this work?');
5};

در جاوا اسکریپت، زمانی که از کلمه کلیدی varبرای تعریف متغیر استفاده می‌شود، خود اعلان در بالای محدوده قرار می‌گیرد. این به این معنی است که حتی اگر متغیر در کد پایین‌تر اعلان شود، مفسر همچنان با آن طوری رفتار می‌کند که انگار در بالا اعلان شده است. با این حال، وقتی با استفاده از عبارت تابع (مانند «var express = function() {...}») توابعی به آن متغیر اختصاص داده می‌شود، این تخصیص شامل Hoisting در جاوا اسکریپت نخواهد شد. بنابراین، وقتی کاربری بخواهد expression()‎را قبل از اختصاص تابع به آن فراخوانی کند، مفسر expression()‎را به‌عنوان متغیری می‌بیند که هنوز تابعی به آن اختصاص داده نشده است که این امر منجر به «خطای نوع» (TypeError) می‌شود زیرا به عنوان نوعی تابع قابل فراخوانی نیست.

ترتیب اولویت در اعلان های جاوا اسکریپت

هنگام اعلام توابع و متغیرها در جاوا اسکریپت، توجه به اصول زیر بسیار حائز اهمیت است:

  • تخصیص متغیر بر اعلان تابع اولویت دارد.
  • اعلان تابع بر اعلان‌های متغیر اولویت دارد.
  • اعلان‌های تابع در بالای اعلان‌های متغیر قرار می‌گیرند.

در زیر در قالب مثال‌هایی به این سه اصل پرداخته شده است.

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

توجه به مثال زیر برای نشان دادن اصل اینکه تخصیص متغیر بر اعلان تابع اولویت دارد، مهم است:

1var double = 22;
2
3function double(num) {
4  return (num*2);
5}
6
7console.log(typeof double); // Output: number

در مثال فوق، حتی اگر در ابتدا مقدار 22به متغیر doubleاختصاص داده شود، اعلان تابع بعدی اولویت دارد. بنابراین، هنگامی‌که کاربر بخواهد نوع doubleرا بازیابی کند، نوع  numberرا در خروجی دریافت خواهد کرد زیرا اعلان متغیر به وسیله اعلان تابع لغو می‌شود. مثال زیر هم برای نشان دادن اصل اولویت داشتن اعلان تابع بر اعلان متغیر است:

1var double;
2
3function double(num) {
4  return (num*2);
5}
6
7console.log(typeof double); // Output: function

حتی اگر کاربری بخواهد موقعیت‌های اعلان‌ها را عوض کند، مفسر جاوا اسکریپت همچنان doubleرا به عنوان نوعی تابع شناسایی می‌کند. این نشان می‌دهد که اعلان‌های تابع اولویت بیشتری نسبت به اعلان‌های متغیر دارند. این تأثیر متقابل بین اعلان‌های تابع و اعلان‌های متغیر بر ماهیت سلسله مراتبی مدیریت جاوا اسکریپت با این موجودیت‌ها تأکید می‌کند.

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

مفهوم Hoisting در جاوا اسکریپت برای کلاس‌ها نیز به کار می‌رود. مشابه توابع، کلاس‌های جاوا اسکریپت نیز می‌توانند به طور کلی به دو نوع طبقه‌بندی شوند:

  • «اعلان کلاس» (Class Declarations)
  • «عبارت کلاس» (Class Expressions)

در ادامه به نحوه رفتار Hoisting در جاوا اسکریپت در جاوا اسکریپت برای این دو مفهوم خواهیم پرداخت.

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

مانند اعلان‌های تابع، اعلان‌های کلاس در جاوا اسکریپت از قابلیت Hoisting استفاده می‌کنند. با این حال، آن‌ها تا زمانی که مورد ارزیابی قرار نگیرند، بدون مقدار اولیه باقی می‌مانند. از نظر عملی، این بدان معنی است که کاربر باید کلاس را قبل از اینکه بتواند واقعاً از آن بهره ببر، اعلان کند. مثال زیر برای نشان دادن این موضوع است.

1var Frodo = new Hobbit();
2Frodo.height = 100;
3Frodo.weight = 300;
4console.log(Frodo); // Output: ReferenceError: Hobbit is not defined
5
6class Hobbit {
7  constructor(height, weight) {
8    this.height = height;
9    this.weight = weight;
10  }
11}

همان‌طور که از مثال بالا قابل‌درک است، به جای دریافت undefined، خطای مرجع اتفاق افتاده است. این مشاهدات ثابت می‌کنند که اعلان‌های کلاس از Hoisting در جاوا اسکریپت استفاده می‌کنند. در این رابطه توجه به مثال زیر هم می‌توان به درک بهتر موضوع بسیار کمک کند:

1class Hobbit {
2  constructor(height, weight) {
3    this.height = height;
4    this.weight = weight;
5  }
6}
7
8var Frodo = new Hobbit();
9Frodo.height = 100;
10Frodo.weight = 300;
11console.log(Frodo); // Output: { height: 100, weight: 300 }

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

عبارات کلاس در جاوا اسکریپت

مشابه عبارات تابع، عبارات کلاس در جاوا اسکریپت دارای قابلیت Hoisting نیست. در زیر مثالی با استفاده از عبارت کلاس ناشناس آورده شده است:

1var Square = new Polygon();
2Square.height = 10;
3Square.width = 10;
4console.log(Square); // Output: TypeError: Polygon is not a constructor
5
6var Polygon = class {
7  constructor(height, width) {
8    this.height = height;
9    this.width = width;
10  }
11};

در اینجا مثالی با عبارت کلاس با نام آورده شده است:

1var Square = new Polygon();
2Square.height = 10;
3Square.width = 10;
4console.log(Square); // Output: TypeError: Polygon is not a constructor
5
6var Polygon = class Polygon {
7  constructor(height, width) {
8    this.height = height;
9    this.width = width;
10  }
11};

روش صحیح رسیدگی به این موارد به شرح زیر است:

1var Polygon = class Polygon {
2  constructor(height, width) {
3    this.height = height;
4    this.width = width;
5  }
6};
7
8var Square = new Polygon();
9Square.height = 10;
10Square.width = 10;
11console.log(Square);

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

عبارات کلاس در جاوا اسکریپت

نکته: در مورد اینکه آیا متغیرهای جاوا اسکریپت ES6 که با letو constو همچنین کلاس‌ها اعلام شده‌اند، واقعاً دارای قابلیت Hoisting در جاوا اسکریپت است یا خیر، بحث‌هایی وجود دارد. نظرات در این رابطه متفاوت است، برخی ادعا می‌کنند که آن‌ها قابلیت Hoisting دارند اما بدون مقدار اولیه باقی می‌مانند در حالی که برخی دیگر استدلال می‌کنند که آن‌ها به هیچ شکلی دارای قابلیت Hoisting نیستند.

سخن پایانی

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

در زیر خلاصه‌ای از آنچه در این مطلب ارائه شد، آورده شده است:

  • هنگام استفاده از var در ES5 تلاش برای استفاده از متغیرهای اعلان نشده منجر به این می‌شود که به متغیر مقدار تعریف نشده در طول عمل Hoisting اختصاص داده شود.
  • در ES6، استفاده از متغیرهای اعلام نشده منجر به خطای مرجع می‌شود، زیرا این متغیرها در هنگام اجرا بدون مقدار اولیه باقی می‌مانند.

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

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

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