در مقالات آموزشی ری اکت در بخش اول و دوم توضیحاتی در این حیطه ارائه کردیم، به ادامه آموزش بپردازیم.
بازگشت ضمنی (Implicit Return)
تابعهای Arrow امکان داشتن مقادیر بازگشتی ضمنی را فراهم ساختهاند. این مقادیر بدون استفاده از کلیدواژه return بازگشت مییابند. طرز کار این بازگشت به این صورت است که گزارههای تکخطی در بدنه تابع به صورت زیر تعریف میشوند:
const myFunction = () => 'test'
myFunction() //'test'
مثال دیگر زمانی است که یک شیء بازگشت میدهیم. دقت کنید که باید آکولادها را درون پرانتزها قرار دهید تا با پرانتزهای تشکیل دهنده بدنه تابع اشتباه گرفته نشوند:
const myFunction = () => ({ value: 'test' })
myFunction() //{value: 'test'}
طرز کار this در تابعهای Arrow
This مفهومی است که شاید درک آن دشوار باشد، چون بسته به زمینه و همچنین بر اساس حالت جاوا اسکریپت (strict یا غیر آن) متفاوت است.
میبایست این نکته را روشن کنیم، زیرا تابعهای Arrow به طرزی کاملاً متفاوت از تابعهای معمولی عمل میکنند. زمانی که یک متد برای یک شیء تعریف میشود، در تابع معمولی this اشاره به شیء دارد و از این رو میتوان کد زیر را داشت:
const car = {
model: 'Fiesta',
manufacturer: 'Ford',
fullName: function() {
return `${this.manufacturer} ${this.model}`
}
}
بدین ترتیب فراخوانی ()car.fullName مقدار “Ford Fiesta” را بازگشت میدهد.
دامنه this در تابعهای Arrow از زمینه اجرایی به ارث میرسید. یک تابع Arrow به هیچ وجه به this اتصال نمییابد و از این رو مقدار آن در پشته فراخوانی جستجو میشود. بدین ترتیب کدی مانند ()car.fullName کار نخواهد کرد و رشته “undefined undefined” را بازگشت میدهد:
const car = {
model: 'Fiesta',
manufacturer: 'Ford',
fullName: () => {
return `${this.manufacturer} ${this.model}`
}
}
به همین دلیل، تابعهای Arrow به عنوان متدهای شیء مناسب نیستند. همچنین تابعهای Arrow نمیتوانند به عنوان سازنده (constructor) استفاده شوند، زیرا در هنگام مقداردهی اولیه یک خطای TypeError ایجاد میشود.
در این موارد باید از تابعهای معمولی استفاده کرد که زمینه دینامیک مورد نیاز نیست. همچنین این مورد در هنگام مدیرت رویدادها، موجب ایجاد مشکل میشود. شنوندههای رویداد DOM سعی میکنند this را روی عنصر هدف تنظیم کنند و اگر در handler رویداد روی this تکیه کنیم، به یک تابع معمولی نیاز خواهیم داشت:
const link = document.querySelector('#link')
link.addEventListener('click', () => {
// this === window
})
const link = document.querySelector('#link')
link.addEventListener('click', function() {
// this === link
})
Rest و Spread
میتوان یک آرایه، یک شیء یا یک رشته را با استفاده از عملگر spread بسط داد. توضیح خود را با مثالی از آرایه آغاز میکنیم. فرض کنید:
const a = [1، ۲، ۳]
شما میتوانید یک آرایه جدید با کد زیر بسازید:
const c = [...a]
این کد برای شیء نیز به خوبی کار میکند. شیء را با دستور زیر کلون کنید:
const newObj = { ...oldObj }
با استفاده از رشتهها، عملگر spread یک آرایه با هر یک از کاراکترهای رشته ایجاد میکند:
const hey = 'hey'
const arrayized = [...hey] // ['h'، 'e'، 'y']
این عملگر برخی کاربردهای بسیار مفید دارد. مهمترین کاربر توانایی استفاده از یک آرایه به عنوان آرگومان تابع به روشی بسیار ساده است:
const f = (foo، bar) => {}
const a = [1، ۲]
f(...a)
در گذشته این کار را میتوانستید با استفاده از (f.apply(null، a انجام دهید اما این روش زیبا و خوانا نیست. عنصر rest زمانی مفید است که میخواهیم با تخریب آرایه (array destructuring):
const numbers = [1، ۲، ۳، ۴، ۵]
[first، second، ...others] = numbers
و spread عناصر کار کنیم:
const numbers = [1، ۲، ۳، ۴، ۵]
const sum = (a، b، c، d، e) => a + b + c + d + e
const sum = sum(...numbers)
ES2018 مشخصات rest را معرفی کرده است که همین مفهوم اما در مورد شیء را داراست.
مشخصات Rest:
const { first, second, ...others } = {
first: 1,
second: 2,
third: 3,
fourth: 4,
fifth: 5
}
first // 1
second // 2
others // { third: 3, fourth: 4, fifth: 5 }
مشخصات spread امکان ایجاد یک شیء جدید با ترکیب کردن مشخصات شیء ارسالی پس از عملگر spread را میدهد:
const items = { first, second, ...others }
items //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }
تخریب شیء و آرایه
با فرض وجود یک شیء میتوان با استفاده از ساختار تخریب، تنها برخی از مقادیر را استخراج کرد و آنها را در «متغیرهای با نام» قرار داد:
const person = {
firstName: 'Tom',
lastName: 'Cruise',
actor: true,
age: 54 //made up
}
const { firstName: name, age } = person //name: Tom, age: 54
name و age شامل مقادیر مطلوب ما هستند. همین ساختار در مورد آرایهها نیز کار میکند:
const a = [1، ۲، ۳، ۴، ۵]
const [first، second] = a
این گزاره با دریافت آیتمها از اندیسهای ۰، ۱ و ۴، سه متغیر جدید از آرایه a ایجاد میکند:
const [first، second،،، fifth] = a
الفاظ قالبی (Template Literals)
الفاظ قالبی ویژگی جدید ES2015 / ES6 است که امکان کار با رشتهها به روشی کاملاً جدید نسبت به ES5 و قبلتر را فراهم ساخته است.
ساختار آن در نگاه اول بسیار ساده است و کافی است به جای گیومههای تکی یا جفتی از علامت backtick () استفاده کرد:
const a_string = `something`
دقت کنید که این الفاظ کاملاً منحصر به فرد هستند، زیرا ویژگیهای زیادی ارائه میکنند که رشتههای معمولی با گیومه ندارند. از آن جمله:
- ساختاری عالی دارند که امکان تعریف رشتههای چندخطی را میدهد.
- روش آسانی برای میانیابی متغیرها و عبارتها در داخل رشتهها در اختیار ما قرار میدهند.
- امکان ایجاد DSL با استفاده از تگهای قالبی را فراهم میسازند. DSL به معنی «زبان خاص یک حوزه» است و برای مثال در React در کامپوننتهای دارای سبک برای تعریف CSS کامپوننتها استفاده میشوند.)
هر کدام از جزییات فوق را در ادامه بررسی میکنیم.
رشتههای چندخطی
تا قبل از ES6 برای ایجاد یک رشته که در دو یا چند خط گسترش مییابد از کاراکتر \ در انتهای هر خط استفاده میکردیم:
const string =
'first part \
second part'
بدین ترتیب امکان ایجاد یک رشته ۲ خطی پدید میآمد؛ اما تنها در یک خط رندر میشد:
first part second part
برای رندر کردن رشته در چند خط باید به صورت زیر صریحاً از \n در انتهای هر خط استفاده میکردیم:
const string =
'first line\n \
second line'
یا
const string = 'first line\n' + 'second line'
الفاظ قالبی امکان تعریف رشتههای چندخطی را سادهتر ساختهاند.
زمانی که یک لفظ قالبی با backtick باز شود، میتوانید برای ایجاد یک خط جدید از اینتر استفاده کنید و دیگر نیازی به کاراکترهای خاص نیست و همچنان که دیده میشود رندر خواهد شد:
const string = `Hey
this
string
is awesome!`
به خاطر داشته باشید که در این حالت فاصله معنیدار است. از این رو در کد زیر:
const string = `First
قصد داریم یک رشته مانند زیر ایجاد کنیم:
First
Second
یک روش ساده برای اصلاح این مشکل آن است که یک خط خالی داشته باشیم و متد ()trim را درست پس از backtick پایانی قرار دهیم تا هر فاصلهای را پیش از کاراکتر اول حذف کند:
const string = `
First
Second`.trim()
میانیابی
الفاظ قالبی یک روش آسان برای میانیابی متغیرها و عبارتهای درون رشتهها ارائه کردهاند.
این کار با استفاده از ساختار {…}$ ممکن است:
const var = 'test'
const string = `something ${var}` //something test
درون {}$ میتوان هر چیزی حتی عبارتها را اضافه کرد:
const string = `something ${1 + 2 + 3}`
const string2 = `something ${foo() ? 'x' : 'y'}`