در جلسه قبل با برخی از مفاهیم مهم و کلیدی es6 آشنا شدید.در ادامه درس قبل قصد داریم تا شما را با مفاهیم جدیدتر زبان جاوااسکریپت که در دوره React مورد استفاده قرار می گیرد آشنا کنیم.
کاربرد export در جاوااسکریپت
در حالت عادی زمانی که شما بخواهید دستورات جاوااسکریپت خود را بصورت تفکیک شده بنویسید، راهکاری که وجود دارد این است که آنها را درون فایل های اسکریپت مجزا قرار دهید.اما چطور آنها را در html خود فراخوانی کنیم؟
حتما می گویید که کاری ندارد تنها کاری که باید انجام دهیم این است که آنها را به ترتیب و پشت سر هم در فایل html فراخوانی کنیم. بله این یک راه است و راه اشتباهی نیست.اما….
باید بگویم بحث import و export متفاوت است؛ در نوشتن کدهای ماژولار با این دستورات هدف این است که در خود فایل های جاوا اسکریپت از قسمتی از یک فایل جاوا اسکریپت دیگر استفاده کنیم تا خود فایل های جاوا اسکریپت وابستگی های خود را بدانند.
به طور مثال فرض کنید که یک فایل به نام person.js داشته باشیم که دارای یک شیء به نام person باشد.
مثال:
1 2 3 |
const person = { mame: 'Amir' } |
حال چطور دستورات این فایل را برای استفاده در فایل های دیگر خروجی بدهیم؟ توجه داشته باشید تا زمانی که دستوری را از یک فایل خروجی ندهید نمی توانید آن را درون فایل دیگر استفاده کنید.
برای اینکار در انتهای جایی که قصد خروجی دادن دستورات فایل را دارید از کلمه کلیدی export استفاده نمائید.
مثال:
1 2 3 4 5 |
const person = { mame: 'Amir' } export default person; |
منظور از default یعنی بطور پیش فرض مقدار مورد نظر person را خروجی بده.
خروجی دادن چندین دستور از طریق یک فایل
در صورتی که در یک فایل چندین دستور را می خواهید خروجی بدهید باید تک به تک برای آنها از کلمه کلیدی export استفاده کنید.در این حالت حق ندارید از واژه default استفاده نمائید.
در مثال زیر دقیقا دستور خود را مستقیم خروجی داده ایم.
مثال:
1 2 |
export const clean = () => {...} export const baseData = 10; |
کاربرد import در جاوااسکریپت
حال که دستورات یک فایل را خروجی گرفته ایم می توانیم از آنها در یک فایل دیگر استفاده نمائیم. برای اینکار از کلمه کلیدی import در جایی که قصد استفاده کرده از دستورات یک فایل دیگر را دارید استفاده می کنیم.
از آنجا که در فایل person.js برای export کردن شیء person از کلیدواژه default استفاده کرده ایم در هنگام import فقط همان شیء person برای ما import می شود نه هیچ کد دیگری.
مثال:
1 |
import person from './person.js' |
این حالت default در حالت export کردن کمک می کند در حالت import کردن با هر نامی که مدنظرمان است مقدار را دریافت کنیم برای مثال من در اینجا از واژه per برای import کردن کمک می گیرم.
مثال:
1 |
import prs from './person.js' |
پس از نوشتن واژه import آن چیزی که آن فایل خروجی داده را نوشته سپس واژه from را قرار داده و آدرس فایل مورد نظر را درون کوتیشن می نویسیم.
مثال:
1 2 |
import {baseData} from './utility.js' import {clean} from './utility.js' |
اما از آنجا که برای utility.js از default استفاده نکردیم باید مشخص کنیم که چه قسمتی را می خواهیم import کنیم. همانطور که می بینید در کد بالا با استفاده از {} توانسته ایم نام تابع و نام ثابت خود را مشخص کنیم تا import شوند.
به این موارد named export می گوییم چرا که بر اساس نام import یا export می کند.
شما می توانید به جای نوشتن هر بار واژه import برای یک مقدار همگی آن ها را در یک خط نوشته و با , از هم جدا کنید.
مثال:
1 |
import {baseData, clean} from './utility.js' |
همانطور که گفته شد در حالت export default شما می توانید هر نامی را در هنگام import کردن برای مقدار مورد نظر خود وارد کنید.اما اگر قصد دارید همین حالت را برای import چندگانه استفاده کنید باید از کلمه کلیدی as (روش alias (نام مستعار)) بهره بگیرید
مثال:
1 |
import {clean as myFavoriteName} from './utility.js' |
همچنین اگر چندین مقدار در فایلی دارید که می خواهید همه را با هم وارد کنید می توانید از حالت زیر استفاده کنید.در این حالت نام دلخواه ما یک شیء جاوا اسکریپت خواهد بود که حاوی تمام const ها و اطلاعات دیگری است که از طرف فایل مبدا export شده باشند.
مثال:
1 |
import * as bundled from './utility.js' |
نمونه خروجی گرفتن از شی مستعار:
1 2 |
bundled.clean bundled.baseData |
متاسفانه برخی از این ویژگی های جدید ES6 در مدرن ترین مرورگرها هم پشتیبانی نمی شوند.
سوال: چرا از ES6 استفاده می کنیم در حالی که در مرورگرها پشتیبانی نمی شود؟
پاسخ: به سه دلیل اصلی:
- اولا ES6 قابلیت های بسیار خوبی دارد که قدرت برنامه نویسی ما را بیشتر می کند. با استفاده از این قابلیت ها می توانیم برنامه های بهتری نوشته و کدها را سریع تر بنویسیم.
- دوما استفاده از آخرین نسخه جاوا اسکریپت در react تبدیل به یک استاندارد شده است. بنابراین بهتر است ما هم طبق این استاندارد عمل کنیم.
- سوما این ویژگی ها در آینده تبدیل به استاندارد خواهند شد فقط کمی زمان لازم دارند. بنابراین بهتر است آن ها را از همین الان یاد بگیریم تا در آینده نیازی به زحمت اضافی نباشد.
مفهوم class در جاوااسکریپت
یکی دیگر از ویژگی های جدید ES6 کلاس ها هستند. کلاس ها به زبان ساده نقشه کلی برای اشیاء هستند و شکل شماتیک آنها بدین صورت است:
1 2 3 4 |
class Person { name = 'Amir' call = () => {...} } |
کلاس ها می توانند property (خصوصیت) داشته باشند مانند name که برابر با Amir است. همچنین می توانند method داشته باشند که تابعی مثل call خواهد بود. به زبان ساده property ها متغیر هایی هستند که به کلاس تعلق دارند در حالی که method ها توابعی هستند که متعلق به کلاس می باشند.
ساخت شی از روی کلاس
برای ساخت یک شیء از یک کلاس (نمونه سازی) می توانیم بدین صورت عمل کنیم:
1 |
const myPerson = new Person() |
دسترسی به خصوصیات یک کلاس یا شی
برای دسترسی به خصوصیات باید ابتدا شی خود را که ساخته ایم فراخوانی کرده سپس خصوصیت مورد نظر را جلوی آن قرار دهیم.
مثال:
1 2 3 |
myPerson.call() console.log(myPerson.name) //Amir |
ارث بری کلاس یا inheritance
یعنی یک کلاس می تواند خصوصیات و متدها (کدهای) یک کلاس دیگر را به ارث ببرد (از آن ها استفاده کند) بدون اینکه بخواهیم کدها را دوباره تکرار کنیم.برای ارث بری می باید کلاس از کلمه کلیدی extends استفاده نماید.
مثال:
1 |
class Person extends Master |
نحوه نوشتن خصوصیات در یک کلاس
در جاوااسکریپت زمانی که قصد داشته باشید خصوصیتی را تعریف کنید می بایست آن را درون تابع سازنده به نام constructor ایجاد نمائید.
متدها نیز تنها با نام متد و مانند توابع عادی نوشته می شوند.
به مثال زیر دقت کنید:
1 2 3 4 5 6 7 8 9 |
class Person { constructor(){ this.name = 'Amir Javanmir'; } printMyName () { console.log(this.name); } } |
در کلاس Person ابتدا یک خصوصیت به نام name تعریف کرده ایم. همانطور که گفته شد برای تعریف خصوصیت ها باید از یک تابع constructor به همراه کلیدواژه this استفاده کنید. این this به همین آبجکتی که از روی کلاس قرار است ساخته شود اشاره می کند.
سپس متدی به نام printMyName تعریف کرده ایم که name را نمایش می دهد. this.name یعنی همین name ای که در همین کلاس تعریف شده است.
حالا می توانید یک نمونه (شیء) از این کلاس بسازیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Person { constructor() { this.name = 'Amir Javanmir'; } printMyName() { console.log(this.name); } } const person = new Person(); person.printMyName(); //Amir Javanmir |
حالا برای مبحث وراثت می توانیم کلاس دیگری به این شکل تعریف کنیم:
1 2 3 4 5 6 7 8 9 |
class Human { constructor (){ this.gender = 'male'; } printGender() { console.log(this.gender); } } |
حالا اگر کلاس Person کلاس Human را extend کند (یعنی بسط و گسترش دهد – همان وراثت) می تواند از خصوصیات و متدهای Human نیز استفاده کند!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class Human { constructor (){ this.gender = 'male'; } printGender() { console.log(this.gender); } } class Person extends Human { constructor() { this.name = 'Amir Javanmir'; } printMyName() { console.log(this.name); } } |
حالا اگر کد زیر را بنویسیم چه می شود؟
1 2 |
const person = new Person(); person.printGender(); |
به خطا برمیخوریم! در جاوا اسکریپت اگر کلاسی دارید که کلاس دیگری را extend می کند و از constructor هم استفاده می کند باید از متد خاصی به نام ()super در constructor کلاس خود که ارث بری کرده است استفاده کنید. بنابراین برای کلاس Person می گوییم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class Human { constructor (){ this.gender = 'male'; } printGender() { console.log(this.gender); } } class Person extends Human { constructor() { super(); this.name = 'Amir Javanmir'; } printMyName() { console.log(this.name); } } const person = new Person(); person.printGender(); //male |
تابع super در واقع constructor کلاس پدر را صدا میزند تا خصوصیت شما ساخته شود و به کلاس فرزند منتقل شود.
شما می توانید به کلاس خود رفته و مقدار gender را نیز تغییر بدهید!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class Human { constructor (){ this.gender = 'male'; } printGender() { console.log(this.gender); } } class Person extends Human { constructor() { super(); this.name = 'Amir Javanmir'; this.gender = 'female'; } printMyName() { console.log(this.name); } } const person = new Person(); person.printGender(); //female |