ما در راهنمای اختصاص دادن متغیر و جهش در JavaScript ، به مواردی با جهش متغیر و نحوه مدیریت آنها پرداختیم. در این مقاله ، خواهیم دید که چگونه روش های آرایه ای که جهش آرایه اصلی را ایجاد می کنند ، زندگی را برای ما دشوار می کند. اما همه اینها نابودی و تاریکی نیست. ما روش های آرایه تغییرناپذیری را برای رفع این مشکلات خواهیم نوشت – و شما امروز می توانید استفاده از آنها را در کد خود شروع کنید.

در کتاب جدید من با جزئیات بیشتر این موضوع را کاوش کنید و با JavaScript مدرن سرعت بگیرید بیاموزید که با JavaScript کدگذاری کنید.

جهش های آرایه ای در JavaScript

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

در اینجا مثالی آورده شده است که نشان می دهد چگونه می تواند به طور بالقوه باعث برخی مشکلات شود:

const numbers = [1,2,3];
const countdown = numbers.reverse();

این کد خوب به نظر می رسد ما یک آرایه داریم به نام numbers، و ما می خواهیم آرایه دیگری به نام countdown که اعداد را به ترتیب معکوس لیست می کند. و به نظر می رسد که م workثر است. اگر مقدار را بررسی کنید countdown متغیر ، همان چیزی است که انتظار داریم:

عارضه جانبی ناخوشایند این عمل این است که reverse() روش جهش یافته است numbers آرایه نیز هست. این اصلاً چیزی نیست که ما می خواستیم:

حتی بدتر ، هر دو متغیر به یک آرایه یکسان اشاره می کنند ، بنابراین هر تغییری که متعاقباً در یکی ایجاد کنیم بر دیگری تأثیر می گذارد. فرض کنید ما از Array.prototype.push() روش برای افزودن مقدار 0 تا انتهای countdown آرایه. این همان کار را به numbers آرایه (زیرا هر دو به یک آرایه ارجاع می دهند):

countdown.push(0)
<< 4
countdown
<< [3,2,1,0]
numbers
<< [3,2,1,0]

این نوع از عوارض جانبی است که می تواند مورد توجه قرار نگیرد – به خصوص در یک برنامه بزرگ – و ایجاد اشکال بسیار سخت برای ردیابی می کند.

روش های آرایه قابل تغییر در JavaScript

و reverse تنها روش آرایه ای نیست که باعث این نوع شیطنت جهش می شود. در اینجا لیستی از روش های آرایه وجود دارد که آرایه ای را که فراخوانی شده است تغییر می دهد:

کمی گیج کننده است ، آرایه ها همچنین برخی از روش ها را دارند که آرایه اصلی را تغییر نمی دهد ، اما به جای آن یک آرایه جدید باز می گرداند:

این روش ها براساس عملیاتی که انجام داده اند ، آرایه جدیدی را برمی گردانند. به عنوان مثال map() از روش می توان برای دو برابر کردن تمام اعداد در یک آرایه استفاده کرد:

const numbers = [1,2,3];
const evens = numbers.map(number => number * 2);
<< [2,4,6]

حالا اگر بررسی کنیم numbers آرایه ، می توانیم ببینیم که با فراخوانی روش تحت تأثیر قرار نگرفته است:

به نظر می رسد هیچ دلیلی وجود ندارد که چرا برخی از روش ها آرایه را جهش می دهند و برخی دیگر این کار را نمی کنند. اما روند افزوده های اخیر این است که آنها را غیر جهش نمی دهیم. به سختی می توان یادآوری کرد که کدام یک از آنها را انجام می دهد

یاقوت به روش استفاده از علامت گذاری انفجار راه حل خوبی برای این مسئله دارد. هر روشی که باعث تغییر دائمی شی شود که آن را صدا می زند ، با یک صدا ختم می شود. [1,2,3].reverse! آرایه را معکوس خواهد کرد ، در حالی که [1,2,3].reverse آرایه جدیدی را با عناصر معکوس برمی گرداند.

روشهای آرایه غیرقابل تغییر: بیایید این ظروف متحرک را برطرف کنیم!

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

نوشتن برخی از توابع که به جای جهش در آرایه اصلی ، یک شی ar آرایه جدید را برمی گردانند ، چندان سخت نیست. این توابع روش های آرایه تغییرناپذیر ما هستند.

چون ما قصد نداریم پچ میمون Array.prototype، این توابع همیشه خود آرایه را به عنوان اولین پارامتر می پذیرند.

ترکیدن

بیایید با نوشتن مطلب جدید شروع کنیم pop تابعی که کپی از آرایه اصلی را باز می گرداند اما بدون آخرین مورد است. توجه داشته باشید که Array.prototype.pop() مقداری را که از انتهای آرایه ظاهر شده است برمی گرداند:

const pop = array => array.slice(0,-1);

این تابع استفاده می کند Array.prototype.slice() برای بازگرداندن یک نسخه از آرایه ، اما با حذف آخرین مورد. استدلال دوم -1 یعنی قبل از پایان برش 1 مکان را متوقف کنید. نحوه کارکرد این را در مثال زیر می بینیم:

const food = ['🍏','🍌','🥕','🍩'];
pop(food)
<< ['🍏','🍌','🥕']

فشار دادن

بعد ، بیایید یک ایجاد کنیم push() تابعی که آرایه جدیدی را باز می گرداند ، اما یک عنصر جدید به انتهای آن اضافه شده است:

const push = (array, value) => [...array,value];

این از اپراتور spread برای ایجاد کپی از آرایه استفاده می کند. سپس مقدار ارائه شده به عنوان آرگومان دوم را به انتهای آرایه جدید اضافه می کند. مثالی در اینجا آورده شده است:

const food = ['🍏','🍌','🥕','🍩'];
push(food,'🍆')
<< ['🍏','🍌','🥕','🍩','🍆']

Shift و Unshift

ما می توانیم جایگزینی برای Array.prototype.shift() و Array.prototype.unshift() به طور مشابه:

const shift = array => array.slice(1);

برای ما shift() تابع ، ما در حال برش اولین عنصر از آرایه به جای آخرین مورد هستیم. این را می توانید در مثال زیر مشاهده کنید:

const food = ['🍏','🍌','🥕','🍩'];
shift(food)
<< ['🍌','🥕','🍩']

ما unshift() متد یک آرایه جدید را با مقدار جدیدی که به آغاز از آرایه:

const unshift = (array,value) => [value,...array];

عملگر spread به ما اجازه می دهد مقادیر را به هر ترتیب در داخل آرایه قرار دهیم. ما به راحتی ارزش جدید را قرار می دهیم قبل از نسخه آرایه اصلی. نحوه کارکرد آن را در مثال زیر می بینیم:

const food = ['🍏','🍌','🥕','🍩'];
unshift(food,'🍆')
<< ['🍆','🍏','🍌','🥕','🍩']

معکوس

حالا بیایید شروع کنیم به نوشتن جایگزینی برای Array.prototype.reverse() روش. به جای تغییر در آرایه اصلی ، یک نسخه از آرایه را به ترتیب معکوس برمی گرداند:

const reverse = array => [...array].reverse();

این روش هنوز از Array.prototype.reverse() روش ، اما به کپی آرایه اصلی که ما با استفاده از عملگر گسترش می دهیم اعمال می شود. جهش یک شی object مشکلی ندارد بلافاصله. مستقیما پس از ایجاد آن ، کاری است که ما در اینجا انجام می دهیم. می توانیم ببینیم که در مثال زیر کار می کند:

const food = ['🍏','🍌','🥕','🍩'];
reverse(food)
<< ['🍩','🥕','🍌','🍏']

انشعاب

در آخر ، بیایید با Array.prototype.splice(). این یک عملکرد بسیار عام است ، بنابراین ما به طور کامل کارهایی را که انجام می دهد بازنویسی نمی کنیم (هرچند که این یک کار غیر عادی است) تمرین جالب برای امتحان. (نکته: از عملگر گسترش استفاده کنید و splice()در عوض ، ما به دو کاربرد اصلی برش خواهیم پرداخت: حذف موارد از یک آرایه و قرار دادن موارد در آرایه.

حذف یک مورد آرایه

بیایید با یک تابع شروع کنیم که یک آرایه جدید را باز می گرداند ، اما با حذف یک مورد در یک فهرست مشخص:

const remove = (array, index) => [...array.slice(0, index),...array.slice(index + 1)];

این استفاده می کند Array.prototype.slice() آرایه را به دو نیمه تقسیم کنید – هر دو طرف موردی که می خواهیم حذف کنیم. برش اول یک آرایه جدید را برمی گرداند ، عناصر آرایه اصلی را کپی می کند تا قبل از فهرست قبل از آرگومان مشخص شده. برش دوم ، آرایه ای را با عناصر پس از آرایه ای که حذف می کنیم ، تا انتهای آرایه اصلی برمی گرداند. سپس هر دو را با استفاده از عملگر spread درون آرایه جدیدی قرار می دهیم.

با تلاش برای حذف مورد موجود در فهرست 2 در ، می توانیم این موارد را بررسی کنیم food آرایه زیر:

const food = ['🍏','🍌','🥕','🍩'];
remove(food,2)
<< ['🍏','🍌','🍩']

افزودن یک مورد آرایه

در آخر ، بیایید تابعی بنویسیم که یک آرایه جدید را با مقدار جدیدی که در یک شاخص خاص درج شده است بازگرداند:

const insert = (array,index,value) => [...array.slice(0, index), value, ...array.slice(index)];

این کار به روشی مشابه با remove() تابع. این دو برش از آرایه ایجاد می کند ، اما این بار عنصر موجود در شاخص ارائه شده را شامل می شود. وقتی دو برش را کنار هم قرار می دهیم ، مقدار ارائه شده را به عنوان استدلال بین هر دو قرار می دهیم.

با تلاش برای قرار دادن یک شکلک کیک کوچک در وسط خود ، می توانیم این کارها را بررسی کنیم food آرایه:

const food = ['🍏','🍌','🥕','🍩']
insert(food,2,'🧁')
<< ['🍏','🍌','🧁','🥕','🍩']

اکنون مجموعه ای از روش های آرایه تغییرناپذیر داریم که آرایه های اصلی ما را تنها می گذارد. من همه آنها را ذخیره کردم یک مکان در CodePen، بنابراین در صورت تمایل آنها را کپی کرده و در پروژه های خود استفاده کنید. می توانید با ساختن روش های یک شی single از آنها ، نام فضا بگیرید یا فقط در صورت لزوم از آنها استفاده کنید.

این موارد برای اکثر عملیات آرایه باید کافی باشد. اگر می خواهید عملیاتی دیگر انجام دهید ، قانون طلایی را بخاطر بسپارید: ابتدا با استفاده از عملگر گسترش نسخه ای از آرایه اصلی تهیه کنید. سپس، بلافاصله. مستقیما هر روش جهش را در این نسخه اعمال کنید.

نتیجه

در این مقاله ، ما بررسی کردیم که چگونه JavaScript زندگی را با روش های آرایه ای که آرایه اصلی را به عنوان بخشی از زبان جهش می دهند ، دشوار می کند. سپس روشهای آرایه تغییرناپذیر خود را برای جایگزینی این توابع نوشتیم.

آیا روش های آرایه دیگری وجود دارد که بتوانید از داشتن نسخه غیر قابل تغییر بهره مند شوید؟ چرا دست دراز نمی کنیم توییتر به من اطلاع دهید

فراموش نکنید که کتاب جدید من را بررسی کنید بیاموزید که با JavaScript کدگذاری کنید اگر می خواهید با JavaScript مدرن سرعت بگیرید.