دِستراکچرینگ (Destructuring) در جاوااسکریپت یعنی چه؟

سلام و عرض ادب خدمت شما دوستان عزیز?.

یکی از جالب‌ترین و کاربردی‌ترین ویژگی‌هایی که به جاوااسکریپت در ES6 اضافه شده Destructuring (دِستراکچرینگ) هست که با اون می‌تونیم خلاصه‌تر، خواناتر و مدرن‌تر کدنویسی کنیم. ما دو نوع Destructuring داریم:

۱. Array Destructuring (برای آرایه‌ها)
۲. Object Destructuring (برای آبجکت‌ها)


۱. Array Destructuring

اگه آرایه‌ای داریم به صورت زیر:

const users = [&quotMario&quot, &quotEmily&quot, &quotJohn&quot, &quotAllie&quot];

و اگه بخوایم همه (یا بعضی از) اعضای آرایه رو بریزیم توی متغیرهای اختصاصی، می‌تونیم از Array Destructuring استفاده کنیم:

const users = [&quotMario&quot, &quotEmily&quot, &quotJohn&quot, &quotAllie&quot];

 const [mario, emily, john, allie] = users;

console.log(mario);
console.log(allie);

کدی که توی خط ۳ نوشتیم، ۴ متغیر با اسم‌هایی که بین براکت‌ها [...] با کاما جدا کردیم می‌سازه و مقدارشون رو با توجه به ترتیب قرار گرفتن اونها، از آرایه می‌خونه و به اونها نسبت میده. در واقع کد خط ۳ مشابه کد زیر هست:

const mario = users[0];
const emily = users[1];
const john  = users[2];
const allie = users[3];

همونطور که می‌بینیم باید به صورت دستی برای هر یک از اعضای آرایه یک متغیر درست کنیم و با توجه موقعیتِ عضو آرایه به اون مقدار بدیم. اما با Destructuring خیلی راحت‌تر و خلاصه‌تر می‌تونیم چنین کاری رو انجام بدیم.

توی Array Destructuring ترتیب اهمیت داره. یعنی مقدار اولین آیتمی که توی براکت‌ها قرار می‌گیره، اولین عضو آرایه هست، مقدار دومین آیتم، دومین عضو آرایه و ... .


اگه فقط به بعضی اعضا احتیاج داریم

اگه فقط به بعضی از اعضای آرایه احتیاج داریم، مثلاً اولین و آخرین عضو، می‌تونیم از کد زیر استفاده کنیم:

const users = [&quotMario&quot, &quotEmily&quot, &quotJohn&quot, &quotAllie&quot];

const [mario, , , allie] = users;

console.log(mario);
console.log(allie);

همونطور که گفتیم، چون ترتیب اهمیت داره، باید خونه‌های میانی رو خالی بذاریم تا بتونیم مقدار درستی رو نسبت بدیم به آخرین متغیر.

رست (Rest) اینجا هم کاربرد داره. می‌تونیم برای چند عضو ابتدایی، متغیرهایی اختصاصی درست کنیم و بقیه اعضا رو با استفاده از رست بریزیم توی یک آرایه جدا:

const numbers = [1, 2, 3, 4, 5, 6];

const [one, two, ...others] = numbers;

alert(one);    // 1
alert(others); // 3,4,5,6

console.log(others); // [3, 4, 5, 6]

اگه این کد رو اجرا کنیم و کنسول رو ببینیم، مقدار متغیر others یک آرایه هست شامل همه اعضای آرایه به غیر از اولین و دومین. دقت کنیم که عضوِ رست باید آخرین عضو باشه. در غیر این صورت خطا می‌گیریم:

const numbers = [1, 2, 3, 4, 5, 6];

const [one, two, ...others, ] = numbers;

// SyntaxError: rest element may not have a trailing comma


اگه تعداد متغیرها بیشتر از اعضای آرایه باشن

اگه تعداد متغیرهایی که سمت چپ تعریف می‌کنیم، بیشتر از تعداد اعضای آرایه باشه، اعضای اضافی با مقدار undefined پیاده‌سازی میشن:

const numbers = [1, 2];

const [one, two, three, four] = numbers;

console.log(two);   // 2
console.log(three); // undefined

برای جلوگیری از پیاده‌سازی شدن یک متغیر با مقدار undefined، می‌تونیم به متغیر مقدار پیشفرض بدیم تا در صورتی که مقدار نظیر اون توی آرایه undefined بود، مقدار پیشفرض در نظر گرفته بشه برای متغیر:

const numbers = [1, 2, undefined];

const [one, two, three = 3, four = 4] = numbers;

console.log(two);   // 2
console.log(three); // 3
console.log(four);  // 4




۲. Object Destructuring

این تکنیک توی آبجکت‌ها، با پراپرتی‌های یک آبجکت سر و کار داره و با اون می‌تونیم راحت‌تر و خلاصه‌تر پراپرتی‌های یک آبجکت رو بریزیم توی متغیرهای اختصاصی:

const user = {
  name: &quotEmily&quot,
  age: 4,
  role: &quotAdmin&quot,
}

 const { name, age, role } = user;

console.log(name); // Emily
console.log(role); // Admin

توی خط ۷ و توی براکت‌های منحنی {...} اسم پراپرتی‌هایی رو نوشتیم که به اونها احتیاج داریم. کد بالا بدون Destructuring مشابه کد زیر هست:

const user = {
  name: &quotEmily&quot,
  age: 4,
  role: &quotAdmin&quot,
}

 const name = user.name;
 const age  = user.age;
 const role = user.role;

console.log(name); // Emily
console.log(role); // Admin

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

توی Object Destructuring ترتیب اهمیتی نداره. اما چیزی که مهمه اینه که آبجکت سمت راست، باید پراپرتی‌هایی همنام با متغیرهای که سمت چپ تعریف می‌کنیم داشته باشه. توی مثال ابتدایی مطمئن هستیم که آبجکت user پراپرتی‌هایی به اسم‌های name و age داره؛ اما متغیرها می‌تونن بدون نیاز به حفظ ترتیب تعریف بشن:

const user = {
  name: &quotEmily&quot,
  age: 4,
  role: &quotAdmin&quot,
}

const { role, name, age } = user;

console.log(name); // Emily
console.log(role); // Admin


اگه پراپرتی وجود نداشت

اگه متغیری تعریف کنیم که اسم اون در بین پراپرتی‌های آبجکت وجود نداره، متغیر با undefined پیاده‌سازی میشه:

const user = {
  name: &quotEmily&quot,
  age: 4,
  role: &quotAdmin&quot,
}

const { firstname } = user;

console.log(firstname); // undefined

اما می‌تونیم یک مقدار پیشفرض به چنین متغیرهایی بدیم.

مقدار پیشفرض برای متغیرها

اگه پراپرتی مد نظر توی آبجکت وجود نداشت، می‌تونیم به شکل زیر به اون مقدار پیشفرض بدیم:

const user = {
  name: &quotEmily&quot,
  age: 4,
}

 const { name, role = &quotGuest&quot } = user;

console.log(name); // Emily
console.log(role); // Guest


اسم دلخواه برای متغیرها

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

const user = {
  name: &quotEmily&quot,
  age: 4,
  role: &quotAdmin&quot,
}

 const { name: firstname, role: title } = user;

console.log(firstname); // Emily
console.log(title);     // Admin


مقدار پیشفرض برای متغیرهای با اسم دلخواه

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

const user = {
  name: &quotEmily&quot,
  age: 4,
}

 const { name, role: title = &quotGuest&quot } = user;

console.log(name);  // Emily
console.log(title); // Guest


Object Destructuring و پارامتر توابع

یکی از پرکاربردترین قسمت‌هایی که Object Destructuring استفاده میشه، توی پارامترهای توابع هست:

function welcome({ name, role }) {
  console.log(`Welcome ${name}. You're ${role}`);
}

const mario = { name: &quotMario&quot, role: &quotAdmin&quot };
const emily = { name: &quotEmily&quot, role: &quotWriter&quot };

welcome(mario);
welcome(emily);

تابع welcome بدون Destructuring مشابه تابع زیر هست:

function welcome(user) {
  const name = user.name;
  const role = user.role;

  console.log(`Welcome ${name}. You're ${role}`);
}




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

function welcome({ name: firstname, role: title = &quotGuest&quot }) {
   console.log(`Welcome ${firstname}. You're ${title}`);
}

const mario = { name: &quotMario&quot, role: &quotAdmin&quot };
const emily = { name: &quotEmily&quot};

welcome(mario);
welcome(emily);


به عنوان آخرین مثال، می‌خوایم کدی رو بررسی کنیم که توی اون داخل Array Destructuring یک Object Destructuring داریم:

const users = [
  { name: &quotMario&quot, age: 3 },
  { name: &quotEmily&quot, age: 5 },
];

 const [{name: mariosName}] = users;

alert(mariosName); // Mario

خب دوستان با تکنیک Destructuring آشنا شدیم و دیدیم که چطوری می‌تونیم کوتاه‌تر و خواناتر و البته با ظاهری مدرن‌تر کدنویسی کنیم. روزتون خوش ??


Resources: developer.mozilla.org