داستان {سه نقطه} در جاوااسکریپت

گردآوری و تالیف : فاطمه شیرزادفر
تاریخ انتشار : 25 بهمن 1398
دسته بندی ها : جاوا اسکریپت

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

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

این سه نقطه پشت سرهم دارای دو معنای متفاوت است: اپراتور Spread (به معنای گسترش دادن) و اپراتور Rest (به معنای استراحت کردن).

اپراتور Spread

Spread به ما این امکان را می‌دهد که به عنوان مثال عناصر یک آرایه را به طور جداگانه داخل یک آرایه دیگر قرار دهیم.

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

const newArray = ['first', ...anotherArray];

پارامتر Rest

پارامتر rest به ما این اجازه را می‌دهد که تعداد نامحدودی از آرگومان‌ها را به عنوان یک آرایه نمایش دهیم. پارامترهای نام‌گذاری شده می‌توانند جلوی پارامتر rest قرارگیرند.

const func = (first, second, ...rest) => {};

موارد کاربرد

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

کپی کردن آرایه

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

const fruits = ['apple', 'orange', 'banana'];
const fruitsCopied = [...fruits]; // ['apple', 'orange', 'banana']

console.log(fruits === fruitsCopied); // false

// old way
fruits.map(fruit => fruit);

در این جا هر عنصر از آرایه  fruits را انتخاب کرده و سپس هر‌کدام را درون ارایه‌ی جدیدی قرار می‌دهیم.

همچنین می‌توانیم با استفاده از متد map کپی آرایه را بدست آوریم (روش قدیمی).

آرایه‌های غیر تکراری

می‌خواهیم عناصر تکراری درون آرایه را حذف کنیم. خب ساده‌ترین راه حل برای آن چیست؟

آبجکت set فقط می‌تواند این عناصر غیر تکراری را در خود ذخیره کند، و آن‌ها را در یک آرایه جمع کند. همچنین این کار، عناصر تکراری را هم درون خود نگه می‌دارد، پس ما می‌توانیم آن را در یک آرایه جدید spread کنیم و خروجی آن، یک آرایه با عناصر غیر تکراری است.

const fruits = ['apple', 'orange', 'banana', 'banana'];
const uniqueFruits = [...new Set(fruits)]; // ['apple', 'orange', 'banana']

// old way
fruits.filter((fruit, index, arr) => arr.indexOf(fruit) === index);

متصل کردن دو آرایه با یکدیگر

ما می‌توانیم با استفاده از متد concat دو آرایه جداگانه را به هم متصل کنیم، ولی چرا در این جا هم از spread استفاده نکنیم؟

const fruits = ['apple', 'orange', 'banana'];
const vegetables = ['carrot'];
const fruitsAndVegetables = [...fruits, ...vegetables]; // ['apple', 'orange', 'banana', 'carrot']
const fruitsAndVegetables = ['carrot', ...fruits]; // ['carrot', 'apple', 'orange', 'banana']

// old way
const fruitsAndVegetables = fruits.concat(vegetables);
fruits.unshift('carrot');

قرار دادن آرگومان‌ها به‌عنوان آرایه

وقتی آرگومان‌ها ( به عنوان مثال x,y,z : ) جایی قرار دارند که spread هم هست، خوانایی کد ما بالاتر می‌رود. تا قبل از ES6، ما مجبور بودیم که فانکشن‌ها را روی آرگومان‌ها اعمال کنیم، اما حالا می‌توانیم، تنها با استفاده از spread پارامتر‌ها را برای فانکشن بفرستیم، که نتیجه آن کد مرتب‌تری خواهد بود.

const mixer = (x, y, z) => console.log(x, y, z);
const fruits = ['apple', 'orange', 'banana'];

mixer(...fruits); // 'apple', 'orange', 'banana'

// old way
mixer.apply(null, fruits);

برش دادن یک آرایه

برش دادن با متد slice قطعا بسیار راحت‌تر خواهد بود، اما اگر می‌خواهید، می‌توانید از spread در این مورد هم استفاده کنید. در این روش باید عناصری که باقی می‌ماند را تک تک نام گذاری کنید. پس این روش چندان خوبی برای برش یک آرایه بزرگ از وسط نیست!

const fruits = ['apple', 'orange', 'banana'];
const [apple, ...remainingFruits] = fruits; // ['orange', 'banana']

// old way 
const remainingFruits = fruits.slice(1);

تبدیل آرگومان‌ها به یک آرایه

آرگومان‌ها در جاوا اسکریپت array-like object (آبجکت‌هایی که شبیه به آرایه‌ها می‌باشند) هستند. شما می‌توانید با استفاده از اندیس‌ها به آن دسترسی پیدا کنید، اما نمی‌توانید متدهای آرایه را مثل map و filter را برای آن صدا بزنید.

آرگومان‌ها آبجکت‌های قابل تکرار هستند. خب پس با آن‌ها چه کنیم؟! 

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

const mixer = (...args) => console.log(args);
mixer('apple'); // ['apple']

تبدیل Nodelistها (مجموعه ای از گره‌ها) به یک آرایه

آرگومان‌ها مثل یک nodelist هستند، که از تابع querySelectorAll ، return (برگرداننده) شده‌اند. همچنین آن‌ها کمی مثل آرایه‌ها رفتار می‌کنند اما متدهای مناسب و خوبی ندارند.

[...document.querySelectorAll('div')];

// old way
Array.prototype.slice.call(document.querySelectorAll('div'));

کپی کردن یک Object

سرانجام ، به دستکاری object ها رسیدیم. کپی کردن آن‌ها به همان روش کپی کردن آرایه‌ها کار می‌کند. اوایل این کار با object.assign یا یک object literal خالی قابل انجام بود.

const todo = { name: 'Clean the dishes' };
const todoCopied = { ...todo }; // { name: 'Clean the dishes' }
console.log(todo === todoCopied); // false

// old way
Object.assign({}, todo);

ترکیب Objectها

تنها تفاوتی که در ترکیب کردن وجود دارد این هست که properties هایی که کلید‌های یکسانی دارند (در مثال پایین مانند name) رونویسی یا به اصطلاح Overwritten می‌شوند.

Properties های سمت راستی دارای اولویت بالاتری هستند.

const todo = { name: 'Clean the dishes' };
const state = { completed: false };
const nextTodo = { name: 'Ironing' };
const merged = { ...todo, ...state, ...nextTodo }; // { name: 'Ironing', completed: false }

// old way
Object.assign({}, todo, state, nextTodo);

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

تقسیم یک رشته به کاراکتر

و اما آخرین مورد درباره رشته‌ها است. شما می‌توانید یک رشته را با استفاده از spread به کاراکتر‌ها تقسیم کنید. البته اگر بخواهید متد split را هم با یک رشته خالی صدا کنید، نتیجه‌ی یکسانی خواهد داشت.

همین! تمام شد! 

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

و اکنون اکثر مرورگرها از این Syntax جدید پشتیبانی می‌کنند؛ شما می‌توانید تمامی مثال‌های بالا را هنگام خواندن این مقاله در کنسول مرورگر خود امتحان کنید.

در هر صورت شما شروع به استفاده از spread و rest می‌کنید و این یک ویژگی جدید و عالی برای زبانی است که باید از آن آگاهی داشته باشید.

منبع

مقالات پیشنهادی