برنامه نویسی 258 بازدید

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

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

توجه داشته باشید که آنچه در ادامه آمده است تنها فصل اول این مجموعه مطلب را شامل می‌شود و برای مطالعه فصول بعدی باید به بخش‌های آتی این سری مقالات مراجعه کنید.

مقدمه‌ای بر یک کتابخانه View به نام React

در این بخش React و ماهیت آن را توضیح می‌دهیم.

React چیست؟

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

هدف اولیه React این بوده است ساخت یک رابط و حالت آن را در هر زمان با تقسیم کردن رابط و حالت آن در هر زمان به کاری آسان تبدیل کند.

چرا React چنین محبوب است؟

React به طوری طوفانی دنیای توسعه وب فرانت‌اند را تسخیر کرده است. برای این وضعیت چند دلیل می‌توان برشمرد.

پیچیدگی آن کمتر از جایگزین‌های دیگر است

در هنگامی که React انتشار یافت، Ember.js و Angular 1.x گزینه‌های غالب فریمورک‌ها محسوب می‌شوند. هر دو این موارد چنان دستکاری‌هایی در کد می‌کنند که پورت کردن یک اپلیکیشن موجود به کار دشواری تبدیل می‌شود.

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

زمان‌بندی عالی

در برهه‌ای از زمان نسخه دوم انگولار (Angular 2.x) از سوی گوگل معرفی شد که با نسخه‌های قبل تطبیق نمی‌یافت و تغییرات زیادی در آن رخ داده بود. حرکت از انگولار 1 به 2 مانند رفتن به یک فریمورک جدید بود. همچنین بهبود سرعت اجرایی که React نوید می‌داد، موجب شد که اغلب توسعه‌دهندگان React را انتخاب کنند.

پشتیبانی از سوی فیسبوک

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

آیا یادگیری React آسان است؟

گرچه گفتیم که React نسبت به جایگزین‌های خود ساده‌تر است؛ اما استفاده عملی از آن همچنان پیچیده است؛ با این حال، اغلب پیچیدگی React در فناوری‌های جانبی که در آن ادغام می‌شوند مانند Redux و GraphQL است.

React خودش یک API بسیار کوچک دارد. اساساً برای آغاز کار با آن به درک چهار مفهوم زیر نیاز دارید:

  • کامپوننت‌ها
  • JSX
  • حالت
  • Props

همه این مفاهیم و موارد بیشتر در این مجموعه مطلب توضیح داده شده‌اند.

چگونه React را روی رایانه محیط توسعه خود نصب کنیم؟

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

بارگذاری مستقیم React در صفحه وب

ساده‌ترین روش افزودن فایل جاوا اسکریپت React به صفحه به صورت مستقیم است. این روش در مواردی که اپلیکیشن React با عناصر موجود روی یک صفحه منفرد تعامل خواهد داشت و به صورت مستقیم کل جنبه ناوبری را کنترل نمی‌کند بهترین گزینه محسوب می‌شود. در این حالت 2 تگ اسکریپت به تگ body اضافه می‌کنیم:

نسخه 16.7.0-alpha.2 در لینک‌ها به جدیدترین نسخه ری‌اکت در زمان نگارش این مجموعه مطلب یعنی 16.7 آلفا اشاره می‌کند که در آن قابلیت Hook ارائه شده است. در صورتی که نسخه جدیدتری وجود دارد باید از آن استفاده کنید.

بدین ترتیب React و React DOM را بارگذاری می‌کنیم. اما شاید از خود بپرسید چرا 2 کتابخانه بارگذاری شده است؟ چون React 100% مستقل از مرورگر عمل می‌کند و می‌تواند خارج از آن (برای مثال روی دستگاه‌های موبایل با استفاده از React Native) نیز فعال باشد. از این رو باید React Dom نیز بارگذاری شود تا پوشش‌های مناسب مرورگر را اضافه کند.

پس از این که آن تگ‌ها اشاره شد می‌توانید فایل‌های جاوا اسکریپت خود را که از React استفاده می‌کنند بارگذاری کنید و یا این که کد جاوا اسکریپت را در یک تگ Script به صورت inline درج کنید:

برای استفاده از JSX باید یک مرحله دیگر نیز طی کنید که مرحله بارگذاری Babel است:

بدین ترتیب اسکریپت‌ها با نوع MIME خاص text/babel بارگذاری می‌شوند:

<script src="app.js" type="text/babel"></script>

اینک می‌توانید JSX را به فایل app.js خود اضافه کنید:

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

چگونه از create-react-app استفاده کنیم؟

create-react-app یک پروژه است که هدف آن ایجاد امکان راه‌اندازی پروژه‌های ری‌اکت در کمترین زمان ممکن است و هر اپلیکیشن create-react-app که بیشتر از یک صفحه داشته باشد، create-react-app این نیاز را رفع می‌کند.

در ابتدا از npx استفاده می‌کنیم که یک روش آسان برای دانلود و اجرای دستورهای Node.js بدون نصب آن‌ها است. npx به همراه npm عرضه می‌شود و اگر npm را روی سیستم نصب ندارید، باید همین الان آن را از آدرس (+) نصب کنید.

اگر مطمئن نیستید که کدام نسخه از npm را نصب کنید، باید دستور npm –v را اجرا کنید تا نیاز به‌روزرسانی را بررسی کنید.

زمانی که دستور <npx create-react-app <app-name را اجرا بکنید، npx شروع به دانلود جدیدترین نسخه create-react-app کرده، آن را اجرا و سپس از روی سیستم حذف می‌کند. این وضعیت عالی است، زیرا شما هرگز نسخه قدیمی از آن روی سیستم خود نخواهید داشت و هر بار که آن را اجرا کنید، جدیدترین و بهترین کد ممکن را دریافت می‌کنید. با استفاده از دستور زیر آن را اجرا کنید:

npx create-react-app todolist

 create-react-app

زمانی که اجرای آن پایان یابد با تصویر زیر مواجه می‌شوید:

 create-react-app

create-react-app یک ساختار فایل در پوشه‌ای که تعیین کرده‌اید (در این مثال totolist) ایجاد می‌کند و یک ریپازیتوری Git نیز مقداردهی می‌کند.

همچنین چند دستور را در فایل اضافه می‌کند به طوری که می‌توانید بی‌درنگ اپلیکیشن خود را با رفتن به پوشه مربوطه و اجرای دستور npm start آغاز کنید:

create-react-app علاوه بر npm start، چند دستور دیگر نیز اضافه می‌کند:

  • npm run build – برای ساختن فایل‌های اپلیکیشن React در پوشه build، که آماده انتشار روی سرور است.
  • npm test – برای اجرای مجموعه تست با استفاده از Jest
  • Npm eject – برای خارج شدن از create-react-app

خارج شدن یا eject به حالتی گفته می‌شود که تشخیص می‌دهید create-react-app وظیفه خود را انجام داده است، اما می‌خواهید کارهای بیشتری از آنچه create-react-app مجاز است انجام دهید. از آنجا که create-react-app مجموعه‌ای از قراردادهای مشترک و مقدار کمی از گزینه‌های اختیاری است، این احتمال وجود دارد که در مواردی به چیز خاصی نیاز داشته باشید که از ظرفیت‌های create-react-app فراتر می‌رود.

بدین ترتیب زمانی که eject می‌کنید، امکان به‌روزرسانی خودکار را از دست می‌دهید؛ اما می‌توانید با استفاده از پیکربندی Balel و Webpack انعطاف‌پذیری بیشتری به دست آورید.

باید بدانید که عمل eject برگشت‌ناپذیر است. شما 2 پوشه در دایرکتوری اپلیکیشن خود به نام‌های config و scripts به دست می‌آورید. این پوشه‌ها شامل پیکربندی‌ها هستند و اینک می‌توانید شروع به ویرایش آن‌ها بکنید.

اگر از قبل یک اپلیکیشن ری‌اکت داشته باشید که با استفاده از نسخه‌های قدیمی ری‌اکت ساخته شده است، ابتدا باید نسخه آن را با استفاده از (console.log(React.version در اپلیکیشن خود تست کنید و سپس می‌توانید با اجرای دستور yarn add react@16.7 آن را به‌روزرسانی کنید. بدین ترتیب yarn به شما هشدار می‌دهد که باید به‌روزرسانی کنید. دقت کنید که عدد نسخه مورد نظرتان باید جدیدترین نسخه باشد.

CodeSandbox

یک روش آسان برای این که ساختار create-react-app را بدون نصب کردن آن به دست بیاورید این است که به آدرس https://codesandbox.io/s بروید و گزینه React را انتخاب کنید.

CodeSandbox روشی عالی برای آغاز یک پروژه ری‌اکت بدون نیاز به نصب محلی است.

Codepen

Codepen نیز یک گزینه عالی محسوب می‌شود. شما می‌توانید از پروژه استارتر Codepen که از قبل با React پیکربندی شده است و از hook ها نیز پشتیبانی می‌کند استفاده کنید.

Pen-های Codepen برای پروژه‌های سریع با یک فایل جاوا اسکریپت عالی هستند؛ در حالی که project-ها برای پروژه‌های با چندین فایل مانند آن‌هایی که در اغلب موارد هنگام ساخت اپلیکیشن‌های ری‌اکت استفاده می‌کنیم مناسب هستند.

نکته‌ای که باید اشاره کنیم این است که Codepen به دلیل طرز کار درونی خود نیازی به استفاده ساختار import برای ماژول‌های معمولی ES ندارد، بلکه می‌توان برای مثال useState را با استفاده از دستور زیر ایمپورت کرد:

const { useState } = React

و نه دستور زیر:

import { useState } from 'react'

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

اینک به فصل اول راهنمای React رسیده‌ایم. با ما همراه باشید.

آیا قبل از یادگیری عملی React باید چیزی را بیاموزیم؟

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

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

متغیرها

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

به همین دلیل است که جاوا اسکریپت در مواردی یک زبان برنامه‌نویسی «فاقد نوع» (untyped) نامیده می‌شود. متغیر باید پیش از استفاده، اعلان شود. 2 روش برای انجام این کار وجود دارد که شامل استفاده از کلیدواژه‌های var ،let یا const است. تفاوت این سه روش در نوع تعامل بعدی با متغیر است.

استفاده از var

تا ES2015 کلیدواژه var تنها سازه موجود برای تعریف کردن متغیرها بود.

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

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

اگر متغیری را هنگام اعلان کردن، مقداردهی نکنید، دارای مقدار undefined خواهد بود تا این که مقداری به آن انتساب داده شود.

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

همچنین می‌توانید متغیرهای چندگانه‌ای را به یکباره در گزاره واحد اعلان کنید:

دامنه (scope) متغیر بخشی از کد است که متغیر در آن قابل مشاهده است.

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

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

باید دقت کنید که یک بلوک (که به وسیله آکولادها مشخص می‌شود) دامنه جدیدی تعریف نمی‌کند. دامنه جدید تنها زمانی که یک تابع ایجاد شود تعریف می‌شود، زیرا var دارای دامنه بلوکی نیست بلکه دامنه تابعی دارد.

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

استفاده از let

Let ویژگی جدیدی است که در ES2015 معرفی شده است. در واقع let یک نسخه دارای دامنه بلوکی از var محسوب می‌شود. دامنه آن به بلوک، گزاره یا عبارتی که در آن تعریف می‌شود و همه بلوک‌های درونی که داخل آن بلوک قرار دارند، مربوط می‌شود.

توسعه‌دهندگان جاوا اسکریپت مدرن، در غالب موارد صرفاً از let استفاده می‌کند و استفاده از var را کنار گذارده‌اند. تعریف کردن let در خارج از هر تابع، برخلاف var باعث ایجاد یک متغیر سراسری نمی‌شود.

استفاده از const

متغیرهایی که با var و let اعلان ‌شوند، می‌توانند در ادامه در برنامه تغییر یابند و مجدداً مقادیری به آن‌ها انتساب یابد. زمانی که یک const مقداردهی بشود، مقدار آن نمی‌تواند دیگر تغییر یابد و نمی‌توان مقدار دیگری به آن انتساب داد.

بدین ترتیب دیگر نمی‌توان مقادیر دیگری به const با نام a انتساب داد. با این حال می‌توان a را در صورتی که شیئی باشد که متدهایی برای تغییر محتوای خود داشته باشد، تغییر داد.

Const تغییرناپذیری را تضمین نمی‌کند و صرفاً این اطمینان را می‌دهد که ارجاع را نمی‌توان تغییر داد. Const مانند let دارای دامنه بلوکی است.

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

تابع‌های Arrow

تابع‌های Arrow در ES6 / ECMAScript 2015 معرفی شده‌اند و از زمان معرفی خود، روش نمایش و کارکرد کدهای جاوا اسکریپت را برای همیشه تغییر داده‌اند. این تغییر چنان مثبت بوده است که دیگر به ندرت استفاده از کلیدواژه function را در کدهای مدرن می‌بینید.

این ساختار از نظر بصری ساده و خوشایند است و امکان نوشتن تابع‌هایی با ساختار کوتاه‌تر را فراهم ساخته است. بدین ترتیب ساختار زیر:

به حالت زیر تغییر یافته است:

اگر بدنه تابع تنها شامل یک گزاره باشد، می‌توان پرانتزها را حذف کرد و همه آن را در یک خط نوشت:

پارامترها درون پرانتزها ارسال می‌شوند:

اگر یک پارامتر داشته باشید و این تنها پارامتر شما باشد، می‌توانید پرانتزها را به طور کامل حذف کنید:

به لطف این ساختار کوتاه، تابع‌های Arrow استفاده از تابع‌های کوچک را ترویج داده‌اند.

بازگشت ضمنی (Implicit Return)

تابع‌های Arrow امکان داشتن مقادیر بازگشتی ضمنی را فراهم ساخته‌اند. این مقادیر بدون استفاده از کلیدواژه return بازگشت می‌یابند. طرز کار این بازگشت به این صورت است که گزاره‌های تک‌خطی در بدنه تابع به صورت زیر تعریف می‌شوند:

مثال دیگر زمانی است که یک شیء بازگشت می‌دهیم. دقت کنید که باید آکولادها را درون پرانتزها قرار دهید تا با پرانتزهای تشکیل دهنده بدنه تابع اشتباه گرفته نشوند:

طرز کار this در تابع‌های Arrow

This مفهومی است که شاید درک آن دشوار باشد، چون بسته به زمینه و همچنین بر اساس حالت جاوا اسکریپت (strict یا غیر آن) متفاوت است.

می‌بایست این نکته را روشن کنیم، زیرا تابع‌های Arrow به طرزی کاملاً متفاوت از تابع‌های معمولی عمل می‌کنند. زمانی که یک متد برای یک شیء تعریف می‌شود، در تابع معمولی this اشاره به شیء دارد و از این رو می‌توان کد زیر را داشت:

بدین ترتیب فراخوانی ()car.fullName مقدار “Ford Fiesta” را بازگشت می‌دهد.

دامنه this در تابع‌های Arrow از زمینه اجرایی به ارث می‌رسید. یک تابع Arrow به هیچ وجه به this اتصال نمی‌یابد و از این رو مقدار آن در پشته فراخوانی جستجو می‌شود. بدین ترتیب کدی مانند ()car.fullName کار نخواهد کرد و رشته “undefined undefined” را بازگشت می‌دهد:

به همین دلیل، تابع‌های Arrow به عنوان متدهای شیء مناسب نیستند. همچنین تابع‌های Arrow نمی‌توانند به عنوان سازنده (constructor) استفاده شوند، زیرا در هنگام مقداردهی اولیه یک خطای TypeError ایجاد می‌شود.

در این موارد باید از تابع‌های معمولی استفاده کرد که زمینه دینامیک مورد نیاز نیست. همچنین این مورد در هنگام مدیرت رویدادها، موجب ایجاد مشکل می‌شود. شنونده‌های رویداد DOM سعی می‌کنند this را روی عنصر هدف تنظیم کنند و اگر در handler رویداد روی this تکیه کنیم، به یک تابع معمولی نیاز خواهیم داشت:

Rest و Spread

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

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

این کد برای شیء نیز به خوبی کار می‌کند. شیء را با دستور زیر کلون کنید:

با استفاده از رشته‌ها، عملگر spread یک آرایه با هر یک از کاراکترهای رشته ایجاد می‌کند:

این عملگر برخی کاربردهای بسیار مفید دارد. مهم‌ترین کاربر توانایی استفاده از یک آرایه به عنوان آرگومان تابع به روشی بسیار ساده است:

در گذشته این کار را می‌توانستید با استفاده از (f.apply(null، a انجام دهید اما این روش زیبا و خوانا نیست. عنصر rest زمانی مفید است که می‌خواهیم با تخریب آرایه (array destructuring):

و spread عناصر کار کنیم:

ES2018 مشخصات rest را معرفی کرده است که همین مفهوم اما در مورد شیء را داراست.

مشخصات Rest:

مشخصات spread امکان ایجاد یک شیء جدید با ترکیب کردن مشخصات شیء ارسالی پس از عملگر spread را می‌دهد:

تخریب شیء و آرایه

با فرض وجود یک شیء می‌توان با استفاده از ساختار تخریب، تنها برخی از مقادیر را استخراج کرد و آن‌ها را در «متغیرهای با نام» قرار داد:

name و age شامل مقادیر مطلوب ما هستند. همین ساختار در مورد آرایه‌ها نیز کار می‌کند:

این گزاره با دریافت آیتم‌ها از اندیس‌های 0، 1 و 4، سه متغیر جدید از آرایه a ایجاد می‌کند:

الفاظ قالبی (Template Literals)

الفاظ قالبی ویژگی جدید ES2015 / ES6 است که امکان کار با رشته‌ها به روشی کاملاً جدید نسبت به ES5 و قبل‌تر را فراهم ساخته است.

ساختار آن در نگاه اول بسیار ساده است و کافی است به جای گیومه‌های تکی یا جفتی از علامت backtick (`) استفاده کرد:

دقت کنید که این الفاظ کاملاً منحصر به فرد هستند، زیرا ویژگی‌های زیادی ارائه می‌کنند که رشته‌های معمولی با گیومه ندارند. از آن جمله:

  • ساختاری عالی دارند که امکان تعریف رشته‌های چندخطی را می‌دهد.
  • روش آسانی برای میان‌یابی متغیرها و عبارت‌ها در داخل رشته‌ها در اختیار ما قرار می‌دهند.
  • امکان ایجاد DSL با استفاده از تگ‌های قالبی را فراهم می‌سازند. DSL به معنی «زبان خاص یک حوزه» است و برای مثال در React در کامپوننت‌های دارای سبک برای تعریف CSS کامپوننت‌ها استفاده می‌شوند.)

هر کدام از جزییات فوق را در ادامه بررسی می‌کنیم.

رشته‌های چندخطی

تا قبل از ES6 برای ایجاد یک رشته که در دو یا چند خط گسترش می‌یابد از کاراکتر \ در انتهای هر خط استفاده می‌کردیم:

بدین ترتیب امکان ایجاد یک رشته 2 خطی پدید می‌آمد؛ اما تنها در یک خط رندر می‌شد:

first part second part

برای رندر کردن رشته در چند خط باید به صورت زیر صریحاً از \n در انتهای هر خط استفاده می‌کردیم:

یا

الفاظ قالبی امکان تعریف رشته‌های چندخطی را ساده‌تر ساخته‌اند.

زمانی که یک لفظ قالبی با backtick باز شود، می‌توانید برای ایجاد یک خط جدید از اینتر استفاده کنید و دیگر نیازی به کاراکترهای خاص نیست و همچنان که دیده می‌شود رندر خواهد شد:

به خاطر داشته باشید که در این حالت فاصله معنی‌دار است. از این رو در کد زیر:

قصد داریم یک رشته مانند زیر ایجاد کنیم:

یک روش ساده برای اصلاح این مشکل آن است که یک خط خالی داشته باشیم و متد ()trim را درست پس از backtick پایانی قرار دهیم تا هر فاصله‌ای را پیش از کاراکتر اول حذف کند:

میان‌یابی

الفاظ قالبی یک روش آسان برای میان‌یابی متغیرها و عبارت‌های درون رشته‌ها ارائه کرده‌اند.

این کار با استفاده از ساختار {…}$ ممکن است:

درون {}$ می‌توان هر چیزی حتی عبارت‌ها را اضافه کرد:

کلاس‌ها

در سال 2015 و با معرفی استاندارد ECMAScript 6 یا ES6، مفهوم کلاس معرفی شد.

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

افرادی که با سابقه یادگیری زبان‌های برنامه‌نویسی جاوا یا پایتون یا دیگر زبان‌ها به سراغ جاوا اسکریپت می‌آیند، برای درک ماهیت وراثت پروتوتایپی با مشکل مواجه می‌شوند و از این رو کمیته ECMAScript تصمیم گرفت تا این تغییر ظاهری در ساختار (syntactic sugar) را بر مبنای وراثت پروتوتایپی پیاده کند به طوری که شبیه به طرز کارکرد وراثت مبتنی بر کلاس در زبان‌های برنامه‌نویسی دیگر به نظر بیاید.

نکته مهمی که بدانید این است که جاوا اسکریپت در پس‌زمینه همچنان به صورت قبل عمل می‌کند و شما می‌توانید به طرز معمول به پروتوتایپ یک شیء دسترسی داشته باشید.

تعریف یک کلاس

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

هر کلاس یک شناسه دارد که می‌تواند برای ایجاد یک شیء جدید با استفاده از ()new ClassIdentifier مورد استفاده قرار گیرد. زمانی که یک شیء مقداردهی می‌شود، متد سازنده (constructor) با پارامترهای ارسالی فراخوانی می‌شود.

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

وراثت کلاس

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

اگر کلاسی که به ارث رسیده متدی با همان نام متد کلاس بالاتر در سلسله‌مراتب داشته باشد، نزدیک‌ترین متد، تقدم می‌یابد:

این کد عبارت «.Hello، I am Flavio. I am a programmer» را نمایش می‌دهد.

در کلاس‌ها اعلان متغیر کلاس به صورت صریح وجود ندارد؛ اما می‌بایست هر متغیری که در سازنده قرار دارد را مقداردهی کرد. درون یک کلاس می‌توان با فراخوانی ()super به کلاس والد ارجاع داد.

متدهای استاتیک

به طور معمول متدها در وهله و نه در خود کلاس تعریف می‌شوند؛ اما متدهای استاتیک روی خود کلاس اجرا می‌شوند:

متدهای خصوصی

جاوا اسکریپت یک روش داخلی برای تعریف متدهای خصوصی (private) یا حفاظت‌شده (protected) ندارد. البته برخی راهکارها وجود دارند اما معرفی آن‌ها خارج از حیطه این مقاله است.

Getter-ها و Setter-ها

شما می‌توانید متدهایی با پیشوند get و set برای ایجاد getter و setter تعریف کنید. این دو متد بر اساس این که بخواهید به یک متغیر دسترسی داشته باشید، یا مقدار آن را تغییر دهید فراخوانی می‌شوند:

اگر تنها یک getter داشته باشیم، مشخصه نمی‌تواند تعیین شود و هر تلاشی برای انجام این کار نادیده گرفته می‌شود:

اگر یک setter داشته باشیم، می‌توانیم مقدار را تغییر دهیم؛ اما نمی‌توانیم از بیرون کلاس به آن دسترسی داشته باشیم:

Callback-ها

رایانه‌ها دارای طراحی ناهمگام (asynchronous) هستند. منظور از ناهمگام این است که کارهای مختلف می‌توانند مستقل از گردش‌کار اصلی برنامه اجرا شوند.

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

برنامه‌ها به طور درونی از وقفه‌ها (interrupts) استفاده می‌کنند. منظور از وقفه سیگنالی است که به سمت پردازنده ارسال می‌شود و توجه سیستم را جلب می‌کند.

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

به طور معمول زبان‌های برنامه‌نویسی به صورت «همگام» هستند و برخی از آن‌ها در خود زبان یا کتابخانه‌هایش، روش‌هایی برای مدیریت ناهمگام ارائه می‌کنند. زبان‌های C J،ava ،C# ،PHP ،Go ،Ruby ،Swift و Python همگی به صورت پیش‌فرض همگام هستند. برخی از آن‌ها از رویدادهای ناهمگام با استفاده از نخ‌ها و ایجاد یک پردازش جدید پشتیبانی می‌کنند.

جاوا اسکریپت نیز به صورت پیش‌فرض همگام و تک نخی است. این بدان معنی است که کد نمی‌تواند یک نخ جدید ایجاد کرده و به صورت موازی اجرا شود.

خطوط کد به صورت پشت سر هم یکی پس از دیگری اجرا می‌شوند. برای نمونه:

اما جاوا اسکریپت درون مرورگر متولد شده است و وظیفه اصلی آن در ابتدا این بوده است که به اقدامات کاربر مانند onClick ،onMouseOver ،onChange و onSubmit پاسخ دهد. این کار از طریق مدل برنامه‌نویسی همگام چگونه میسر می‌شود؟

پاسخ در محیط جاوا اسکریپت است. مرورگر روشی برای انجام این کار ارائه می‌کند، یعنی مجموعه‌ای از API-ها ارائه کرده است که می‌تواند این نوع از کارکرد را اجرا کند.

در سال‌های اخیر Node.js به معرفی یک محیط بدون انسداد I/O اقدام کرده است که این مفهوم را برای دسترسی به فایل‌ها، فراخوانی‌های شبکه و غیره بسط می‌دهد.

ما نمی‌توانیم بدانیم که یک کاربر چه هنگام روی یک دکمه کلیک خواهد کرد، بنابراین تنها می‌توانیم یک «دستگیره رویداد» (event handler) برای عمل کلیک تعریف کنیم. این دستگیره رویداد یک تابع می‌پذیرد که هنگام تحریک شدن رویداد فراخوانی خواهد شد:

این همان callback است.

منظور از callback تابع ساده‌ای است که به صورت یک مقدار به تابع دیگر ارسال می‌شود و تنها زمانی اجرا خواهد شد که رویداد رخ دهد. ما به این دلیل می‌توانیم این کار را انجام دهیم که جاوا اسکریپت «تابع‌های درجه اول» (first-class functions) دارد که می‌توانند به متغیرها انتساب یابند و به تابع‌های دیگر ارسال شوند (تابع‌های درجه بالاتر یا higher-order نیز نامیده می‌شوند).

به طور معمول همه کدهای کلاینت در یک دستگیره رویداد load روی شیء window پوشش می‌یابد که تابع callback را تنها زمانی که صفحه آماده است فراخوانی می‌کند:

Callback-ها همه‌جا استفاده می‌شوند و اختصاص به رویدادهای DOM ندارند. یک مثال رایج در استفاده از تایمر چنین است:

درخواست‌های XHR نیز یک callback می‌پذیرند. در این مثال یک تابع به یک مشخصه انتساب می‌یابد که هنگام اتفاق افتادن یک رویداد خاص، فراخوانی می‌شود:

مدیریت خطا در callback-ها

یکی از روش‌های رایج برای مدیریت خطا در callback-ها استفاده از چیزی که است Node.js به خدمت گرفته است و آن پارامتر اول در هر تابع callback است که شیء error یا error-first callbacks نامیده می‌شود.

اگر خطایی وجود نداشته باشد، این شیء nul است. اما اگر خطایی باشد شامل برخی توضیحات در مورد خطا و دیگر اطلاعات خواهد بود:

مشکل callback-ها

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

این فقط یک کد 4 سطحی است؛ اما سطوح تو در تو بودن بیش از این نیز می‌تواند باشد که چندان جالب نیست. چگونه می‌توان این مشکل را حل کرد؟

جایگزین‌های callback

از نسخه ES6 به بعد، جاوا اسکریپت چند ویژگی معرفی کرده است که به ما کمک می‌کند کدهای ناهمگام بنویسیم و درگیر استفاده از callback نیز نشویم:

  • (promises (ES6
  • (Async/Await (ES8

promise-ها

promise-ها یکی از روش‌های نوشتن کد ناهمگام هستند که در آن لازم نیست نگران وجود callback-های زیاد در کد خود باشیم. با این که این ویژگی سال‌ها است که عرضه شده؛ اما در ES2015 استاندارد و معرفی شده‌اند و اینک با معرفی تابع‌های async در ES2017 منسوخ شده‌اند.

تابع‌های Async از API مربوط به promise-ها به عنوان بلوک اصلی سازنده خود استفاده می‌کنند و از این رو درک آن‌ها حتی در صورتی که در کدهای جدید بخواهید از تابع‌های async به جای promise استفاده کنید، ضروری خواهد بود.

توضیح خلاصه طرز کار promise-ها

زمانی که یک promise فراخوانی می‌شود، کار خود را در حالت معلق (pending) شروع می‌کند. این بدان معنی است که تابع فراخوانی کننده به اجرای خود ادامه می‌دهد و در این زمان منتظر promise است تا پردازشش را انجام دهد و بازخوردی به تابع فراخوانی کننده بدهد.

سپس تابع فراخوانی کننده منتظر مقدار بازگشتی از سوی promise در حالت resolved یا در حالت rejected می‌ماند؛ اما می‌دانیم که جاوا اسکریپت ناهمگام است و از این رو تابع در هنگامی که promise مشغول کار است، به اجرای خود ادامه می‌دهد.

چرا API جاوا اسکریپت از promise-ها استفاده می‌کند؟

promise-ها علاوه بر کد اپلیکیشن و کد کتابخانه در API های وب مدرن استاندارد مانند Fetch یا Service Workers نیز استفاده می‌شوند. این که در جاوا اسکریپت مدرن بخواهید از promise-ها استفاده نکنید نامحتمل است و از این رو باید آن‌ها را کاملاً یاد بگیرید.

ایجاد یک promise

API مربوط به promise یک سازنده promise معرفی کرده است که با استفاده از new promise() مقداردهی می‌شود:

همان طور که می‌بینید promise ثابت سراسری done را بررسی می‌کند و اگر true باشد، یک promise به صورت reolved بازگشت می‌یابد و در غیر این صورت مقدار بازگشتی rejected خواهد بود.

ما با استفاده از resolve و reject می‌توانیم یک مقدار را بازگشت دهیم و گرچه در مثال فوق یک رشته بازگشت یافته است؛ اما می‌تواند یک شیء نیز باشد.

مصرف یک promise

در بخش قبلی شیوه ایجاد یک promise را توضیح دادیم. اینک می‌خواهیم ببینیم promise چگونه می‌تواند مصرف شود.

اجرای تابع ()checkIfItsDone باعث راه‌اندازی یک promise به نام ()isItDoneYet می‌شود که با استفاده از یک callback به نام then منتظر resolve شدن می‌ماند و در صورت وجود یک خطا آن را با callback به نام catch مدیریت می‌کند.

زنجیره‌سازی promise-ها

می‌توان یک promise را به promise دیگر بازگشت داد و بدین ترتیب زنجیره‌ای از promise-ها ایجاد کرد. یک مثال عالی از زنجیره‌سازی promise-ها در Fetch API ارائه شده است که یک لایه روی API مربوط به XMLHttpRequest ساخته و می‌توانیم از آن برای دریافت منابع و صف‌بندی یک زنجیره از promise-ها برای اجرا در مواد واکشی منابع استفاده کنیم.

Fetch API یک سازوکار مبتنی بر promise است و فراخوانی ()fetch معادل تعریف کردن promise با استفاده از ()new promise است:

مثال

در این مثال ()fetch را برای دریافت لیستی از آیتم‌های TODO از فایل todos.json در دامنه root فراخوانی می‌کنیم و بدین ترتیب زنجیره‌ای از promise-ها ایجاد می‌شود.

اجرای ()fetch یک پاسخ بازگشت می‌دهد که مشخصات زیادی دارد و درون آن موارد زیر را ارجاع می‌دهیم:

  • Status – یک مقدار عددی است که کد وضعیت HTTP را نشان می‌دهد.
  • statusText – یک پیام وضعیت است که در صورت موفق بودن درخواست، به صورت OK خواهد بود.

Response نیز یک متد Jason است که یک promise بازگشت می‌دهد. این promise با محتوای بدنه پردازش شده و انتقال یافته به JSON به صورت resolve درمی‌آید.

بنابراین با توجه به این promise-ها اتفاقات زیر رخ می‌دهد:

promise نخست در زنجیره یک تابع است که به نام ()status تعریف کرده‌ایم و وضعیت پاسخ را بررسی کرده و در صورت عدم موفقیت (کدهای بین 200 تا 299) promise را رد می‌کند.

این عملیات موجب می‌شود که زنجیره promise-ها قطع شود و مستقیماً به گزاره ()catch در انتها می‌رود و متن Request failed به همراه پیام خطا، log می‌شود.

اما اگر موفق باشد تابع ()json را که تعریف کردیم فرا می‌خواند. از آنجا که وقتی promise قبلی موفق بود، شیء response را بازگشت داده است، ما آن را به عنوان ورودی promise دوم می‌گیریم.

در این حالت داده‌های JSON که پردازش شده را بازگشت می‌دهیم به طوری که promise سوم مستقیماً JSON را بازیابی کند:

و آن را در کنسول log می‌کنیم.

مدیریت خطاها

در مثال فوق در بخش قبلی یک catch داشتیم که به زنجیره promise-ها الحاق می‌شد. زمانی که هر کدام از بخش‌های زنجیره promise-ها از کار می‌افتد و یک خطا رخ می‌دهد و یا پاسخ reject دریافت می‌شود، کنترل به نزدیک‌ترین گزاره ()catch در سمت پایین زنجیره می‌رسد.

آبشارسازی خطاها

اگر درون ()catch خطایی رخ دهد، می‌توانید یک متد ثانویه catch() برای مدیریت آن تعریف کنید و همین طور تا آخر.

هماهنگ‌سازی promise-ها با استفاده از ()promise.all

اگر لازم باشد که promise-های مختلف را با هم هماهنگ کنیم، می‌توانیم از ()promise.all کمک بگیریم و با تعریف کردن لیستی از همه promise-ها، وقتی همه آن‌ها resolve شدند، چیزی را اجرا کنیم.

مثال:

ساختار انتساب تخریب ES2015 امکان انجام این کار را در اختیار ما قرار می‌دهد:

البته شما محدود به استفاده از fetch نیستید و هر promise برای این کار مناسب است.

هماهنگ‌سازی promise-ها با استفاده از ()promise.race

()promise.race به محض این که یکی از promise-ها به صورت resolve شده به آن ارسال شود اجرا می‌شود و callback الحاقی خود را تنها یک بار با نتیجه promise نخست resolve شده اجرا می‌کند. مثال:

Async/Await

جاوا اسکریپت در طی زمان بسیار کوتاهی از callbacks به (promises (ES2015 تکامل یافت و سپس از ES2017 جاوا اسکریپت ناهمگام با معرفی ساختار Async/Await باز هم ساده‌تر شد.

تابع‌های Async ترکیبی از promise-ها و generator-ها هستند و در واقع سطح بالاتری از انتزاع را نسبت به promise-ها ارائه می‌کنند. یک بار دیگر باید تکرار کنیم که async/await بر مبنای promise ساخته شده است.

چرا async/await معرفی شد؟

این ساختار باعث می‌شود که سازه‌های تکراری promise-ها کاهش یابند و محدودیت عدم قطع کردن زنجیره در promise-های زنجیره‌ای نیز رفع شود.

زمانی که promise-ها در ES2015 معرفی شدند، به منظور رفع مشکل کد ناهمگام عرضه شده بودند و در این کار نیز موفق بودند؛ اما در طی 2 سال که ES2015 و ES2017 را از هم جدا می‌ساخت، مشخص شد که promise-ها نمی‌توانند راه‌حل نهایی باشند.

promise-ها برای رفع مشکل مشهور callbak عرضه شدند؛ اما آن‌ها نیز مشکلات خاص خود را داشتند و باعث ایجاد پیچیدگی بیشتر در ساختار می‌شدند.

در ادامه مشخص شد که می‌توان سازه‌های بهتری با ساختارهای مناسب‌تر در اختیار توسعه‌دهنده‌ها قرار داد و هنگامی که زمان مناسب فرارسید، تابع‌های async عرضه شدند.

این تابع‌ها باعث شدند کد طوری به نظر بیاید که گویا همگام است؛ اما ناهمگام بود و در پشت‌صحنه نیز مسدودسازی نداشت.

طرز کار async/await

یک تابع async در عمل مانند مثال زیر یک promise بازگشت می‌دهد:

زمانی که بخواهیم این تابع را فراخوانی کنیم یک await در اول آن می‌گذاریم و کد فراخوانی کننده تا زمانی که promise به صورت resolve شده یا reject شده بازگشت نیافته است متوقف می‌شود. تنها محدودیت این است که تابع کلاینت باید به صورت async تعریف شده باشد. به مثال زیر توجه کنید:

یک مثال ساده

در ادامه مثال ساده‌ای از کاربرد async/await برای اجرای ناهمگام یک تابع را می‌بینید:

کد فوق مواد زیر را در کنسول مرورگر نمایش می‌دهد:

Before
After
I did something //after 3s

Pomise کردن همه چیز

افزودن کلیدواژه async در ابتدای هر تابعی به این معنی است که تابع یک promise بازگشت خواهد داد. حتی اگر این کار به روش صریحی صورت نگیرد در ساز و کار درونی خودش یک promise بازگشت می‌دهد. به همین دلیل است که کد زیر معتبر است:

و همانند کد زیر عمل می‌کند:

خوانایی کد بسیار افزایش می‌یابد

همان طور که در مثال فوق شاهد هستید، کد ما بسیار ساده به نظر می‌رسد. آن را با کدهایی که از promise-های ساده با زنجیره‌سازی و تابع‌های callback استفاده می‌کنند مقایسه کنید.

این مثال بسیار ساده‌ای است و مزیت‌های اصلی زمانی مشخص می‌شوند که از کدهای بسیار پیچیده استفاده می‌کنید. برای نمونه در ادامه یک منبع JSON ارائه شده که آن را با استفاده از promise-ها تجزیه می‌کنیم:

و در ادامه همین کارکرد با استفاده از await/async ارائه شده است:

سری کردن تابع‌های چندگانه async

تابع‌های async می‌توانند به سادگی به حالت زنجیری درآیند و ساختار آن بسیار خوانا‌تر از promise-های ساده خواهد بود:

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

I did something and I watched and I watched as well

دیباگ کردن ساده‌تر

دیباگ کردن promise-ها دشوار است، زیرا دیباگر روی کدهای ناهمگام متوقف نمی‌شود. Async/await این کار را بسیار ساده‌تر ساخته است، زیرا از نظر کامپایلر این کد مانند کدهای همگام است.

ماژول‌های ES

در حالی که Node.js سال‌ها است که از استاندارد CommonJS استفاده می‌کند، اما مرورگرها هرگز یک سیستم module نداشته‌اند، چون هر تصمیم بزرگی مانند سیستم ماژول باید ابتدا از سوی ECMAScript استانداردسازی و سپس از سوی مرورگر پیاده‌سازی شود.

این فرایند استانداردسازی در ES6 تکمیل شد و مرورگرها شروع به پیاده‌سازی این نوع‌بندی استاندارد کرده و تلاش نمودند همه چیز هم‌راستا بماند و به همان روش سابق کار کند. اینک ماژول‌های ES در کروم، سافاری، Edge و فایرفاکس (از نسخه 60) پشتیبانی می‌شوند.

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

ساختار ماژول‌های ES

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

import package from 'module-name'

در حالی که CommonJS از ساختار زیر استفاده می‌کند:

const package = require('module-name')

یک ماژول در واقع یک فایل جاوا اسکریپت قرار دارد که یک یا چند مقدار (شیء، تابع یا متغیر) را با استفاده از کلیدواژه export، اکسپورت می‌کند. برای نمونه ماژول زیر یک تابع اکسپورت می‌کند که یک رشته با حروف بزرگ بازگشت می‌دهد:

uppercase.js

export default str => str.toUpperCase()

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

اکنون هر ماژول دیگر جاوا اسکریپت می‌تواند این کارکرد را که از سوی uppercase.js ارائه شده با ایمپورت کردن آن به دست آورد.

یک صفحه HTML می‌تواند یک ماژول را با استفاده از تگ <script> با خصوصیت ویژه “type=”module اضافه کند:

لازم به ذکر است که هر اسکریپتی که با “type=”module بارگذاری شود در حالت strict خواهد بود. در این مثال ماژول uppercase.js یک اکسپورت پیش‌فرض تعریف می‌کند و وقتی آن را ایمپورت کردیم می‌توانیم از نام ترجیحی خودمان استفاده کنیم:

و می‌توانیم آن را استفاده کنیم:

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

این نیز یک ساختار ایمپورت معتبر است:

اما این ساختار معتبر نیست:

این ساختار یا مطلق است و یا یک./ یا / در ابتدای نام خود دارد.

گزینه‌های ایمپورت/اکسپورت دیگر

ما این مثال را قبلاً دیدیم:

این مثال یک اکسپورت پیش‌فرض ایجاد می‌کند. می‌توانیم با استفاده از ساختار زیر بیش از یک چیز را اکسپورت کنیم:

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

می‌توانیم تنها چند مورد از این اکسپورت‌ها را با بهره‌گیری از انتساب تخریبی ایمپورت کنیم:

می‌توانیم نام هر ایمپورت را برای سهولت با استفاده از as تغییر دهیم:

می‌توانیم ابتدا اکسپورت پیش‌فرض را ایمپورت کنیم و سپس همه اکسپورت‌های غیر پیش‌فرض را به صورت «با نام» ایمپورت کنیم. برای مثال این کار در ایمپورت react زیر صورت گرفته است:

CORS

ماژول‌ها با استفاده از CORS واکشی می‌شوند. این بدان معنی‌ است که اگر اسکریپت‌ها از یک دامنه دیگر مورد ارجاع قرار گیرند، باید یک هدر CORS معتبر داشته باشند که امکان بارگذاری از سایت دیگر را فراهم سازد.

در مورد مرورگرهایی که از ماژول‌ها پشتیبانی نمی‌کنند چه می‌توان کرد؟ در این موارد می‌توان از ترکیبی از “type=”module و nomodule استفاده کرد:

ماژول‌های ES یکی از بزرگ‌ترین ویژگی‌های معرفی شده در مرورگرهای مدرن هستند. ماژول‌ها بخشی از ES6 هستند؛ اما مسیری که برای پیاده‌سازی آن‌ها طی شده بسیار طولانی است. اینک می‌توانیم از آن‌ها استفاده کنیم؛ اما باید به خاطر داشته باشیم که داشتن بیش از چند ماژول ممکن است بر روی عملکرد صفحه تأثیر منفی بگذارد، چون یک گام دیگر به مراحلی که مرورگر باید در زمان اجرا به آن بپردازد می‌افزاید.

با این که ماژول‌های ES وارد مرورگرها شده‌اند؛ Webpack احتمالاً همچنان یکی از بزرگ‌ترین بازیگرها خواهد ماند؛ اما داشتن یک چنین ویژگی که به طور مستقیم در یک زبان ساخته شده است برای یکنواخت سای روش کار ماژول‌ها در سمت کلاینت و Node.js بسیار مفید است. در بخش بعدی این نوشته به فصل دوم راهنمای جامع React با موضوع مفاهیم مفدماتی ری‌اکت می پردازیم.

برای مطالعه بخش دوم این مجموعه مطلب روی لینک زیر کلیک کنید:

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

telegram
twitter

میثم لطفی

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

بر اساس رای 1 نفر

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

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