ES6 و جاوااسکریپت مدرن
بهنام نوبخت · ۱۴۰۵/۷/۱۱
جاوااسکریپت در طول سالها امکانات بسیار زیادی پیدا کرده است. یکی از مهمترین نسخههای جاوااسکریپت، ECMAScript 2015 یا همان ES6 است که امکانات و قابلیتهای جدید و مهمی را به این زبان اضافه کرد.
امروزه در بسیاری از پروژههای جاوااسکریپت، کدهای مدرن با استفاده از قابلیتهایی مانند let، const، Arrow Function، Template Literal، Destructuring، Spread Operator، Rest Parameter، Default Parameter، for...of، Map و Set نوشته میشوند.
بعضی از این مفاهیم را در مقالات قبلی دیدهایم، اما در این مقاله آنها را در قالب جاوااسکریپت مدرن و ES6 منظمتر و عمیقتر بررسی میکنیم.
در این مقاله یاد میگیریم:
ES6 چیست؟
ECMAScript چیست؟
تفاوت
var،letوconstTemplate Literal
Default Parameters
Arrow Function
Destructuring
Spread Operator
Rest Parameter
Enhanced Object Literals
Shorthand Properties
Method Shorthand
for...ofMapSetOptional Chaining
Nullish Coalescing
و چند تکنیک مدرن دیگر
ES6 چیست؟
نام ES6 مخفف:
ECMAScript 6
است.
ECMAScript استانداردی است که جاوااسکریپت بر اساس آن توسعه پیدا میکند.
ES6 در سال 2015 معرفی شد و به همین دلیل با نام:
ES2015
نیز شناخته میشود.
قبل از ES6 نیز جاوااسکریپت وجود داشت، اما ES6 امکانات زیادی را وارد زبان کرد که باعث شدند نوشتن کدهای جاوااسکریپت راحتتر، خواناتر و ساختاریافتهتر شود.
جاوااسکریپت مدرن چیست؟
وقتی درباره Modern JavaScript صحبت میکنیم، معمولاً منظور استفاده از قابلیتهای جدیدتر ECMAScript و روشهای امروزی نوشتن جاوااسکریپت است.
برای مثال کد قدیمی:
var name = "Ali";
در بسیاری از پروژههای جدید به شکل:
const name = "Ali";
نوشته میشود.
var، let و const
یکی از مهمترین تغییرات ES6 معرفی:
let
const
بود.
قبل از ES6 بیشتر از var استفاده میشد.
var
مثال:
var name = "Ali";
console.log(name);میتوان مقدار آن را تغییر داد:
var name = "Ali";
name = "Reza";
console.log(name);let
با let نیز میتوان متغیر ساخت:
let age = 25;
age = 26;
console.log(age);تفاوت مهم let با var در Scope و رفتار آن در Blockها است.
const
برای تعریف مقداری که قصد نداریم متغیر به مقدار دیگری اشاره کند، معمولاً از const استفاده میکنیم:
const country = "Türkiye";نمیتوانیم بعداً بنویسیم:
country = "Iran";این کار باعث خطا میشود.
چه زمانی let و چه زمانی const؟
قاعده ساده:
اگر مقدار متغیر قرار است تغییر کند:
let counter = 0;
counter++;اگر قرار نیست متغیر دوباره مقداردهی شود:
const name = "Ali";در کد مدرن جاوااسکریپت معمولاً بهتر است ابتدا const را در نظر بگیریم و فقط وقتی نیاز به تغییر مقدار داریم از let استفاده کنیم.
Scope در let و const
let و const دارای Block Scope هستند.
مثلاً:
if (true) {
let message = "Hello";
console.log(message);
}اما خارج از Block:
console.log(message);به آن دسترسی نداریم.
Template Literal
یکی از قابلیتهای بسیار کاربردی ES6، Template Literal است.
به جای:
const name = "Ali";
const message =
"Hello " + name;میتوانیم بنویسیم:
const name = "Ali";
const message =
`Hello ${name}`;این روش خواناتر است.
استفاده از چند متغیر
const firstName = "Ali";
const lastName = "Ahmadi";
const age = 25;
const message =
`${firstName} ${lastName} is ${age} years old.`;
console.log(message);استفاده از Expression
داخل ${} میتوانیم Expression نیز قرار دهیم:
const price = 100;
const quantity = 3;
const total =
`Total: ${price * quantity}`;
console.log(total);نتیجه:
Total: 300چند خطی کردن متن
با Template Literal میتوانیم متن چندخطی داشته باشیم:
const message = `
Hello Ali.
Welcome to
جاوااسکریپت.
`;
console.log(message);این قابلیت برای ساخت متنهای پویا بسیار کاربردی است.
Default Parameters
فرض کنید تابعی داریم:
function greet(name) {
console.log(`Hello ${name}`);
}اگر تابع را بدون مقدار اجرا کنیم:
greet();مقدار name برابر undefined خواهد بود.
میتوانیم مقدار پیشفرض تعریف کنیم:
function greet(
name = "Guest"
) {
console.log(`Hello ${name}`);
}حالا:
greet();نتیجه:
Hello Guestاما:
greet("Ali");نتیجه:
Hello AliDefault Parameter برای چند مقدار
function createUser(
name = "Unknown",
age = 0
) {
console.log(name);
console.log(age);
}مثال:
createUser();نتیجه:
Unknown
0Arrow Function
یکی از معروفترین قابلیتهای ES6، Arrow Function است.
تابع معمولی:
function add(a, b) {
return a + b;
}Arrow Function:
const add = (a, b) => {
return a + b;
};Arrow Function کوتاهتر
اگر تابع فقط یک Expression داشته باشد:
const add = (a, b) =>
a + b;این همان مفهوم را دارد.
مثال:
console.log(
add(10, 20)
);نتیجه:
30Arrow Function با یک Parameter
اگر فقط یک Parameter داشته باشیم، میتوانیم پرانتز را حذف کنیم:
const square = number =>
number * number;استفاده:
console.log(
square(5)
);نتیجه:
25البته نوشتن پرانتز نیز کاملاً معتبر است:
const square = (number) =>
number * number;Arrow Function بدون Parameter
اگر هیچ Parameter نداشته باشیم، باید پرانتز قرار دهیم:
const sayHello = () =>
"Hello";Destructuring چیست؟
Destructuring یکی از قابلیتهای مهم ES6 است که اجازه میدهد مقادیر Array یا Propertyهای Object را به شکل سادهتری داخل متغیرها قرار دهیم.
Array Destructuring
فرض کنید:
const numbers = [10, 20, 30];روش معمول:
const first = numbers[0];
const second = numbers[1];با Destructuring:
const [first, second] =
numbers;حالا:
console.log(first);
console.log(second);نتیجه:
10
20نادیده گرفتن مقدار در Array Destructuring
میتوانیم بعضی مقادیر را نادیده بگیریم:
const numbers = [10, 20, 30];
const [
first,
,
third
] = numbers;اکنون:
first = 10
third = 30Destructuring با مقدار پیشفرض
const numbers = [10];
const [
first,
second = 20
] = numbers;نتیجه:
first = 10
second = 20Object Destructuring
فرض کنید:
const user = {
name: "Ali",
age: 25,
city: "Istanbul"
};روش معمول:
const name = user.name;
const age = user.age;با Destructuring:
const {
name,
age
} = user;حالا:
console.log(name);
console.log(age);تغییر نام در Destructuring
میتوانیم نام متغیر را تغییر دهیم:
const user = {
name: "Ali",
age: 25
};
const {
name: userName,
age: userAge
} = user;حالا:
console.log(userName);
console.log(userAge);مقدار پیشفرض در Object Destructuring
const user = {
name: "Ali"
};
const {
name,
age = 18
} = user;در اینجا:
name = "Ali"
age = 18خواهد بود.
Destructuring در Function Parameters
یکی از کاربردهای بسیار مهم Destructuring استفاده مستقیم در Parameter تابع است.
مثلاً:
function showUser({ name, age }) {
console.log(name);
console.log(age);
}سپس:
const user = {
name: "Ali",
age: 25
};
showUser(user);این روش در پروژههای واقعی بسیار رایج است.
Spread Operator
Spread Operator با سه نقطه:
...نوشته میشود.
یکی از کاربردهای آن، ترکیب یا کپی کردن Arrayها است.
مثلاً:
const first =
[1, 2, 3];
const second =
[4, 5, 6];
const result = [
...first,
...second
];
console.log(result);نتیجه:
[1, 2, 3, 4, 5, 6]کپی Array با Spread
const original = [10, 20, 30];
const copy = [...original];اکنون copy یک Array جدید است.
مثلاً:
copy.push(40);
console.log(original);
console.log(copy);نتیجه:
[10, 20, 30]
[10, 20, 30, 40]Spread برای Object
Spread فقط برای Array نیست.
مثلاً:
const user = {
name: "Ali",
age: 25
};
const copy = {
...user
};ترکیب Objectها
const user = {
name: "Ali"
};
const details = {
age: 25,
city: "Istanbul"
};
const result = {
...user,
...details
};
console.log(result);نتیجه:
{
name: "Ali",
age: 25,
city: "Istanbul"
}تغییر Property با Spread
اگر Property تکراری باشد، مقدار بعدی میتواند مقدار قبلی را Override کند.
مثلاً:
const user = {
name: "Ali",
age: 25
};
const updatedUser = {
...user,
age: 26
};حالا:
updatedUser.age = 26است.
این روش یکی از تکنیکهای مهم برای ایجاد نسخه جدیدی از Object بدون تغییر مستقیم Object قبلی است.
Rest Parameter
Rest Parameter نیز با:
...نوشته میشود، اما کاربرد آن با Spread متفاوت است.
Rest برای جمعآوری چند مقدار در یک Array استفاده میشود.
مثال:
function sum(...numbers) {
console.log(numbers);
}استفاده:
sum(10, 20, 30, 40);داخل تابع:
numbers = [10, 20, 30, 40]است.
محاسبه مجموع با Rest
function sum(...numbers) {
let total = 0;
for (const number of numbers) {
total += number;
}
return total;
}استفاده:
console.log(
sum(10, 20, 30)
);نتیجه:
60تفاوت Spread و Rest
اگر سه نقطه برای باز کردن یا پخش کردن مقادیر استفاده شود:
const result = [
...numbers
];Spread است.
اگر برای جمع کردن چند مقدار استفاده شود:
function sum(...numbers) {
}Rest است.
Enhanced Object Literals
ES6 روشهای کوتاهتری برای ساخت Object ارائه میدهد.
فرض کنید:
const name = "Ali";
const age = 25;روش قدیمی:
const user = {
name: name,
age: age
};در جاوااسکریپت مدرن:
const user = {
name,
age
};کافی است.
Method Shorthand
روش قدیمی:
const user = {
sayHello: function () {
console.log("Hello");
}
};روش مدرن:
const user = {
sayHello() {
console.log("Hello");
}
};این روش خواناتر است.
for...of
در مقالات قبلی با حلقههای جاوااسکریپت آشنا شدیم.
یکی از روشهای مناسب برای پیمایش مقادیر قابل پیمایش، for...of است.
مثلاً:
const numbers =
[10, 20, 30];
for (const number of numbers) {
console.log(number);
}نتیجه:
10
20
30for...of با String
for...of فقط برای Array نیست.
مثلاً:
const word = "Hello";
for (const character of word) {
console.log(character);
}هر کاراکتر جداگانه پردازش میشود.
Map
Map یکی از ساختارهای داده جاوااسکریپت است که اجازه میدهد اطلاعات را به شکل:
Key → Valueذخیره کنیم.
مثلاً:
const users = new Map();اضافه کردن اطلاعات به Map
برای اضافه کردن مقدار:
users.set(
"user1",
"Ali"
);
users.set(
"user2",
"Reza"
);دریافت مقدار از Map
console.log(
users.get("user1")
);نتیجه:
Aliبررسی وجود Key
console.log(
users.has("user1")
);نتیجه:
trueحذف مقدار از Map
users.delete("user1");تعداد عناصر Map
console.log(
users.size
);پیمایش Map
for (const [key, value] of users) {
console.log(key);
console.log(value);
}اینجا از Destructuring نیز استفاده کردهایم.
Set
Set ساختاری برای نگهداری مقادیر یکتا است.
مثلاً:
const numbers =
new Set();
numbers.add(10);
numbers.add(20);
numbers.add(10);چون 10 تکراری است، فقط یک بار ذخیره میشود.
مشاهده Set
console.log(numbers);تقریباً:
Set(2) { 10, 20 }بررسی مقدار در Set
console.log(
numbers.has(20)
);نتیجه:
trueحذف مقدار از Set
numbers.delete(20);کاربرد عملی Set
فرض کنید:
const tags = [
"جاوااسکریپت",
"html",
"جاوااسکریپت",
"css",
"html"
];میتوانیم تکراریها را حذف کنیم:
const uniqueTags =
[...new Set(tags)];
console.log(uniqueTags);نتیجه:
[
"جاوااسکریپت",
"html",
"css"
]این یکی از کاربردهای بسیار رایج Set است.
Optional Chaining
Optional Chaining با:
?.نوشته میشود.
فرض کنید:
const user = {
name: "Ali"
};اگر بخواهیم:
console.log(
user.address.city
);را اجرا کنیم، چون address وجود ندارد، خطا رخ میدهد.
با Optional Chaining:
console.log(
user.address?.city
);نتیجه:
undefinedو خطا رخ نمیدهد.
Optional Chaining در Objectهای تو در تو
مثلاً:
const user = {
profile: {
address: {
city: "Istanbul"
}
}
};میتوانیم بنویسیم:
console.log(
user.profile?.address?.city
);Optional Chaining با Function
اگر مطمئن نیستیم یک Property شامل تابع است یا خیر:
user.sayHello?.();در صورتی که تابع وجود داشته باشد، اجرا میشود.
Nullish Coalescing
عملگر:
??زمانی کاربرد دارد که بخواهیم برای null یا undefined یک مقدار پیشفرض تعیین کنیم.
مثلاً:
const name = null;
const result =
name ?? "Guest";
console.log(result);نتیجه:
Guestاگر مقدار موجود باشد:
const name = "Ali";
const result =
name ?? "Guest";نتیجه:
Aliتفاوت ?? و ||
این دو عملگر را نباید کاملاً یکسان در نظر گرفت.
مثلاً:
const count = 0;
console.log(
count || 10
);نتیجه:
10اما:
console.log(
count ?? 10
);نتیجه:
0چون ?? فقط زمانی سراغ مقدار پیشفرض میرود که مقدار null یا undefined باشد.
ترکیب قابلیتهای جاوااسکریپت مدرن
قدرت واقعی این امکانات زمانی مشخص میشود که آنها را با هم ترکیب کنیم.
فرض کنید:
const user = {
name: "Ali",
age: 25,
address: {
city: "Istanbul"
}
};میتوانیم:
const {
name,
age,
address
} = user;
const city =
address?.city ?? "Unknown";
const message =
`${name} is ${age} years old and lives in ${city}.`;
console.log(message);این مثال ترکیبی از:
Destructuring
Optional Chaining
Nullish Coalescing
Template Literal
constاست.
مثال عملی: ساخت Product
فرض کنید اطلاعات محصول:
const product = {
name: "Laptop",
price: 1200,
discount: 100
};با Destructuring:
const {
name,
price,
discount = 0
} = product;قیمت نهایی:
const finalPrice =
price - discount;و نمایش:
const message =
`${name} - Final Price: ${finalPrice}`;
console.log(message);مثال عملی: بهروزرسانی Object
فرض کنید:
const user = {
name: "Ali",
age: 25,
city: "Istanbul"
};میخواهیم سن را تغییر دهیم، بدون اینکه Object اصلی را تغییر دهیم:
const updatedUser = {
...user,
age: 26
};حالا:
console.log(user.age);
console.log(updatedUser.age);نتیجه:
25
26مثال عملی: Function با Rest
function calculateAverage(...numbers) {
if (numbers.length === 0) {
return 0;
}
let total = 0;
for (const number of numbers) {
total += number;
}
return total / numbers.length;
}استفاده:
console.log(
calculateAverage(
10,
20,
30
)
);نتیجه:
20مثال عملی: ترکیب Arrayها
فرض کنید:
const frontend = [
"HTML",
"CSS"
];
const backend = [
"C#",
"SQL"
];ترکیب:
const skills = [
...frontend,
...backend
];نتیجه:
[
"HTML",
"CSS",
"C#",
"SQL"
]جاوااسکریپت مدرن و خوانایی کد
هدف ES6 فقط کوتاهتر کردن کد نیست.
یکی از اهداف مهم این قابلیتها، خوانایی و ساختار بهتر کد است.
مثلاً:
const userName = user.name;
const userAge = user.age;میتواند به شکل:
const {
name: userName,
age: userAge
} = user;نوشته شود.
البته نباید صرفاً برای کوتاه کردن کد از Destructuring یا سایر قابلیتهای جدید استفاده کنیم. مهمتر از کوتاه بودن کد، قابل فهم بودن آن است.
اشتباهات رایج
اشتباه اول: تغییر مقدار const
این کد اشتباه است:
const name = "Ali";
name = "Reza";اگر نیاز به تغییر دارید، از let استفاده کنید.
اشتباه دوم: اشتباه گرفتن Spread و Rest
این دو از یک علامت استفاده میکنند:
...اما کاربردشان متفاوت است.
Spread مقادیر را باز میکند.
Rest مقادیر را جمع میکند.
اشتباه سوم: تصور اینکه Spread یک Deep Copy است
مثلاً:
const copy = {
...user
};یک کپی سطحی یا Shallow Copy ایجاد میکند.
اگر Object دارای Objectهای داخلی باشد، داستان پیچیدهتر میشود و نباید تصور کنیم تمام سطوح به صورت مستقل کپی شدهاند.
اشتباه چهارم: استفاده نادرست از Optional Chaining
Optional Chaining برای جلوگیری از برخی خطاهای دسترسی به مقادیر null یا undefined مفید است، اما نباید بدون دلیل همه Propertyها را با ?. بنویسیم.
اشتباه پنجم: استفاده نادرست از ??
اگر مقدار 0 یا false باید معتبر باقی بماند، ?? میتواند انتخاب مناسبی نسبت به || باشد.
جدول قابلیتهای مهم ES6 و جاوااسکریپت مدرن
قابلیتکاربرد | |
|---|---|
| متغیر قابل تغییر |
| متغیر با Binding غیرقابل انتساب مجدد |
Template Literal | ساخت Stringهای پویا |
Default Parameter | مقدار پیشفرض Parameter |
Arrow Function | Syntax کوتاهتر برای Function |
Destructuring | استخراج مقدار از Array/Object |
Spread | باز کردن مقادیر |
Rest | جمع کردن مقادیر |
Object Shorthand | ساخت کوتاهتر Object |
| پیمایش مقادیر |
| ذخیره Key/Value |
| ذخیره مقادیر یکتا |
Optional Chaining | دسترسی امنتر به Propertyهای احتمالی |
Nullish Coalescing | مقدار پیشفرض برای |
تمرینها
تمرین ۱
یک متغیر با const ایجاد کنید که نام شما را نگه دارد.
سپس یک متغیر let برای سن ایجاد کنید و مقدار آن را تغییر دهید.
تمرین ۲
با Template Literal جمله زیر را ایجاد کنید:
My name is Ali and I am 25 years old.نام و سن باید از متغیر دریافت شوند.
تمرین ۳
تابعی ایجاد کنید که اگر نامی دریافت نکرد، مقدار Guest را استفاده کند.
تمرین ۴
یک Array شامل پنج عدد ایجاد کنید و با Destructuring سه مقدار اول را داخل سه متغیر قرار دهید.
تمرین ۵
دو Array بسازید و با Spread آنها را ترکیب کنید.
تمرین ۶
تابعی با Rest Parameter ایجاد کنید که هر تعداد عدد دریافت کرده و مجموع آنها را برگرداند.
تمرین ۷
یک Object کاربر ایجاد کنید و با Object Destructuring نام و سن را استخراج کنید.
تمرین ۸
یک Array دارای مقادیر تکراری ایجاد کنید و با Set مقادیر تکراری را حذف کنید.
تمرین ۹
یک Object تو در تو ایجاد کنید و با Optional Chaining به یک Property داخلی دسترسی پیدا کنید.
تمرین ۱۰
با ?? برای مقدار null یک مقدار پیشفرض تعیین کنید.
چالش عملی
یک برنامه کوچک برای مدیریت اطلاعات یک کاربر ایجاد کنید.
اطلاعات اولیه:
const user = {
firstName: "Ali",
lastName: "Ahmadi",
age: 25,
skills: [
"HTML",
"CSS",
"جاوااسکریپت"
],
address: {
city: "Istanbul"
}
};برنامه باید:
با Destructuring نام و نام خانوادگی را دریافت کند.
با Template Literal یک پیام معرفی بسازد.
با Optional Chaining شهر را دریافت کند.
اگر شهر وجود نداشت، با
??مقدارUnknownقرار دهد.یک Skill جدید با Spread به Array اضافه کند.
با
Setیک لیست Skill بدون تکرار ایجاد کند.یک تابع با Rest Parameter بسازید که تعداد Skillها را محاسبه کند.
یک Object جدید با Spread ایجاد کنید که سن کاربر در آن تغییر کرده باشد.
در صورت نیاز از Arrow Function استفاده کنید.
هدف این تمرین این است که چند قابلیت جاوااسکریپت مدرن را در یک پروژه کوچک با هم استفاده کنید.
جمعبندی
در این مقاله با بخش مهمی از ES6 و جاوااسکریپت مدرن آشنا شدیم.
یاد گرفتیم:
ES6 یا ES2015 چیست.
ECMAScript چه ارتباطی با جاوااسکریپت دارد.
چگونه از
letوconstاستفاده کنیم.Template Literal چگونه کار میکند.
Default Parameter چیست.
Arrow Function چگونه نوشته میشود.
Array و Object Destructuring چیست.
Spread Operator چگونه کار میکند.
Rest Parameter چه کاربردی دارد.
چگونه Objectها را به شکل کوتاهتر ایجاد کنیم.
for...ofچگونه استفاده میشود.Mapچیست.Setچیست.چگونه مقادیر تکراری را با Set حذف کنیم.
Optional Chaining چیست.
Nullish Coalescing چه کاربردی دارد.
چگونه چند قابلیت مدرن جاوااسکریپت را با یکدیگر ترکیب کنیم.
در این مرحله شما بخش بزرگی از Syntaxهای پرکاربرد جاوااسکریپت را میشناسید و میتوانید کدهای مدرنتر و خواناتری بنویسید.
نظرات
هنوز نظری ثبت نشده است.