ما برنامه نویسی را به عنوان یک فعالیت عمومی و اقدامی برای گسترش یا تغییر عملکرد یک سیستم تعریف میکنیم.
برنامه نویسی فعالیت گستردهای است که هم توسط افراد غیرمتخصص (مثلا کاربرانی که تنظیمات ساعت زنگدار یا تلفن همراه خود را تغییر میدهند) و هم توسط متخصصان (برنامه نویسان کامپیوتر و مخاطبان این مقاله) انجام میشود.
جاوا اسکریپت یکی از محبوبترین زبانهای برنامه نویسی امروزی است. شاید شما به تازگی کار با آن را شروع کرده باشید، شاید هم سالهاست که از آن استفاده میکنید. در هر صورت نمیتوانید این موضوع را انکار کنید که مهمترین و پرکاربردترین نرم افزارهای جهان با جاوا اسکریپت نوشته میشوند. اما سوال اینجاست که چقدر این زبان برنامه نویسی فوقالعاده قدرتمند، گاهی عجیب و غریب و اغلب زیبا را میشناسید.
آیا تا به حال به این فکر کردهاید کدهای نوشته شده چگونه به کامپیوتر میگویند که چه کاری انجام دهد؟
به عنوان مثال عبارت a = a + 2 برای توسعه دهندگان هنگام خواندن و نوشتن قابل فهم است، اما در واقع به شکلی نیست که کامپیوتر بتواند مستقیما آن را درک کند!
به همین منظور یک ابزار جداگانه (مفسر یا کامپایلر) برای ترجمه کدهایی که مینویسید در جهتی که سیستم بتواند آنها را درک کند، استفاده میشود.
برای برخی از زبانها این ترجمه دستورات معمولا هر بار که برنامه اجرا میشود، از بالا به پایین و به صورت خط به خط صورت میگیرد که به آن تفسیر کد میگویند.
برای سایر زبانها هم ترجمه زودتر از موعد یعنی قبل از اجرا انجام شده که به آن کامپایل کد گفته میشود. بنابراین هنگامی که برنامه اجرا میگردد، آنچه در حال اجراست در واقع همان کدهایی است که از قبل کامپایل شدهاند.
معمولا میگویند که جاوا اسکریپت مفسری است، زیرا کد منبع جاوا اسکریپت هر بار که اجرا میگردد پردازش میشود. اما این گفته کاملا دقیق نیست، چرا که موتور جاوا اسکریپت در واقع برنامه را به سرعت کامپایل میکند و سپس بلافاصله کد کامپایل شده را اجرا مینماید.
در ادامه با برخی از مفاهیم ضروری آشنا میشویم که به شما کمک میکند تا دید بهتری از اینکه در پشت صحنه چه اتفاقی میافتد، به دست آورید.
در پایان هم درک عمیقتری از آنچه که هنگام نوشتن یک کد جاوا اسکریپت رخ میدهد، خواهید داشت.
مفاهیمی که در اینجا یاد میگیرید، عبارتند از:
- تجزیهکنندههای سینتکس
- محیطهای واژگان
- زمینه اجرا
ممکن است درک این موضوعات برای عدهای دشوار به نظر برسد، اما قبل از شروع در این مورد به من اعتماد کنید، چرا که یادگیری این موارد اصلا آن طور که به نظر میرسد پیچیده نیست.
تجزیهکننده سینتکس
برنامهای که کد شما را میخواند و تعیین میکند که چه کاری باید انجام دهد و اینکه آیا سینتکس آن معتبر است یا خیر. وقتی کدی را در جاوا اسکریپت مینویسید، به طور خودکار به کامپیوتر نمیگوید که چه کاری انجام دهد. با اینکه شما کد را نوشتهاید، اما افراد دیگر ابزارهایی ساختهاند که کد جاوا اسکریپت شما را به چیزی که برای کامپیوتر قابل فهم باشد تبدیل میکند. به این ابزارها کامپایلر (Compiler) میگویند که گاهی اوقات به عنوان مفسر (Interpreter) نیز شناخته میشوند. مفسرها و کامپایلرها کد شما را کاراکتر به کاراکتر میخوانند و تشخیص میدهند که سینتکس آن معتبر است یا نه. سپس آن را به روشی که کامپیوتر بتواند درک کند، پیادهسازی میکنند.
تمام چیزی که گفته شد ماهیت تجزیهکنندههای سینتکس (Syntax Parser) است. بنابراین زمانی که کد خود را مینویسید، برنامهای وجود دارد و قرار است آنچه را که نوشتهاید به عبارات قابل فهم برای کامپیوتر تبدیل کند.
در پشت پرده چیزی شبیه به تصویر زیر اتفاق میافتد:
فرض کنید یک تابع با یک متغیر در برنامه خود نوشتهاید. آن تابع و متغیر در حافظه کامپیوتر ذخیره میشوند. اما این چیزی است که فقط انسان میتواند آن را درک کند، پس آنچه نوشتهاید برای کامپیوتر ترجمه میشود. یک کامپایلر یا یک مفسر وجود دارد که این کار را انجام میدهد، بین این دو فرایند برنامهای است که ما آن را تجزیهکننده سینتکس مینامیم.
به این صورت که کد شما از طریق آن کاراکتر به کاراکتر مانند f / u / n / c / t / i / o / n عبور میکند و تجزیهکننده یا همان Parser تشخیص میدهد که این یک تابع است. پس باید یک فضای خالی بعد از این وجود داشته باشد، بعد چیزی که بعد از پرانتز نشان داده میشود نام تابع خواهد بود. همه اینها توسط سیستمهایی که شخص دیگری نوشته است ترجمه میشود. در طول فرآیند ترجمه، برنامه نویسانی که کامپایلر را نوشتهاند میتوانند کارهای اضافی دیگری را انجام دهند. بنابراین به یاد داشته باشید کد شما چیزی نیست که مستقیما به کامپیوتر میرسد.
محیط واژگان
Lexical به معنای ارتباط کلمات با یکدیگر است. یعنی در کدی که مینویسید، چیزی به طور فیزیکی قرار دارد. در مثال زیر تابع ()Greet را همراه با متغیری به نام msg در داخل آن داریم. متغیر msg به صورت lexical در تابع قرار میگیرد و مشخص میکند کدی که نوشتهاید به طور فیزیکی در کجا قرار دارد.
در زبانهای برنامه نویسی که محیط واژگان برای آنها مهم است، محل قرارگیری عبارات در حافظه را مشخص میکنند. همچنین نحوه تعامل توابع و عناصر برنامه با یکدیگر نیز توسط این تصمیم تعیین میشود. زیرا برای کامپایلری که برنامه شما را به کد ماشین تبدیل میکند، اهمیت دارد که چیزهای مختلف را کجا قرار میدهید. بنابراین وقتی راجع به Lexical Environment صحبت میکنیم، منظور این است که کد کجا نوشته شده است و چه چیزی در اطراف آن قرار دارد.
زمینه اجرا
Execution Context به این معنی است که یک wrapper برای کمک به مدیریت کد در حال اجرا وجود دارد.
برای این کار محیطهای واژگانی زیادی هستند، مثلا بخشهایی از کد که به صورت فیزیکی به آنها نگاه میکنید. اما اینکه کدام یک در حال اجراست، از طریق چیزی که Execution Context نامیده میشود مدیریت میگردد.
به محض اینکه کد خود را اجرا میکنیم، چیزی به وجود میآید که زمینه اجرای گلوبال را فراهم میآورد:
- Thread of Execution (به معنی تجزیه و اجرای کد به صورت خط به خط)
- Live Memory of Variables with Data (معروف به محیط متغیر گلوبال)
Global Variable Environment به معنای تمام متغیرهای کد است که در دسترس قرار دارند.
هنگامی که یک تابع را اجرا میکنید، یک زمینه اجرایی جدید در زمینه اجرای گلوبال تشکیل میشود.
- Thread of Execution (از تابع اجرای کد خط به خط عبور میکنیم)
- Local Memory (محیط متغیر) در آن هر چیزی که داخل تابع تعریف شده است، ذخیره میشود.
Execution Context در دو عبارت اتفاق میافتد:
Creation Phrase
(توابع و متغیرهای اختصاص داده شده در حافظه کامپیوتر)
در این مرحله دو چیز خاص ایجاد میشود: یک شی گلوبال مانند Window برای مرورگر و یک متغیر به نام this.
Execution Phrase
(توابع و متغیرهای اجرا شده)
در تصویر بالا میبینید که یک محیط اجرای گلوبال وجود دارد و در داخل آن هم یک زمینه اجرای منحصربهفرد از تابع Greet ایجاد میشود. هر بار که یک تابع جدید مینویسید، یک زمینه اجرای منحصربهفرد (گاهی به عنوان Function Execution Context نیز شناخته میشود) شکل میگیرد که معمولا در زمینه اجرای گلوبال قرار میگیرد.
در نهایت JavaScript runtime این contextها را حفظ کرده و به ترتیب آنها را اجرا میکند. پس نتیجه میگیریم Execution Context حاوی کدی است که شما نوشتهاید. البته نمیخواهیم زیاد وارد جزئیات این دو عبارت نمیشویم، چرا که شامل مواردی فراتر از آنچه در کد خود نوشتهاید هستند.
جهت یادآوری کدی که شما به وسیله یک زبان مینویسید برای کامپیوتر ترجمه میشود، همچنین مترجم برنامهای است که شخص دیگری آن را نوشته است، یعنی همان چیزی که کد شما را اجرا میکند و میتواند کارهای دیگری نیز انجام دهد.
زمانی که در مورد زمینه اجرا (Execution Context) صحبت میشود، فقط آن را به عنوان پوششی در نظر بگیرید که به شما کمک میکند کد اجرا شده خود را مدیریت کنید. به عبارت دیگر آن را به عنوان مکانی در نظر بگیرید که کد در آنجا به صورت خط به خط اجرا میشود. در این مورد جزییات بیشتری وجود دارد که در این مقاله نمیگنجد و سعی میکنیم در مطلب دیگری به آن بپردازیم.
خلاصهای از آنچه که گفته شد.
- کدی که ما مینویسیم مستقیما اجرا نمیشود، بلکه موتور جاوا اسکریپت آن را میگیرد و تصمیمگیریهای لازم را انجام میدهد.
- تجزیهکننده سینتکس (Syntax Parser) برنامهای است که کد شما را میخواند و مشخص میکند سینتکس آن معتبر است یا نه.
- محیط واژگان (Lexical Environment) جایی است که مشخص میکند عبارات نوشته شده در کدام بخش حافظه کامپیوتر قرار میگیرند.
- زمینه اجرا (Execution Context) هم بخشی است که به شما کمک میکند کد اجرا شده خود را مدیریت کنید.