تفاوت در کپی سطحی و کپی عمقی در جاوا اسکریپت
خیلی وقتا برامون پیش اومده که یه خواستیم یه متغیر کپی کنیم توی یه متغیر دیگه.فرض کنید این متغیر ما از نوع object یا آرایه باشه.پیش خودمون می گیم خب کاری نداره این مساوی اون قرار میدیم و این کپی میشه توی اون یکی.خب،تا اینجاش خوب بود اما مشکل زمانی پیش میاد که یکی از این دوتا تغییر بدیم. میبینیم که اگر مقداری از این یکی تغییر بدیم اون یکی هم تحت تاثیر قرار میگیره و مقدارش تغییر میکنه ، انگار نه انگار که ین دو تا قرار متفاوت باشن.کپی به این معنی هستش که شما یک عنصر یکسان جدید با ویژگی های آن از نسخه اصلی ایجاد می کنید و انتظار دارید که هنگام تغییر در این نسخه ، عنصر اصلی ثابت بمونه ، اما اگر کپی ایجاد کنید که در نسخه اصلی تغییر کنه ، این یک عنصر اصلی به حساب میادش!
بنابراین قصد دارم توی این مقاله کپی کردن درست یه مقدار توی یه مقدار دیگه بررسی کنم.
قبل از بررسی لازم دو تا اصطلاح با هم یاد بگیریم ، Deep Copy و shallow copy.
توی کپی عمقی یا deep copy وقتی میایم یه کپی ایجاد می کنیم، کپی یکسانی از عنصر اصلی با ویژگی های اون ایجاد می کنیم.نسخه اصلی و کپی به هم متصل نیستن! یعنی اگر خصوصیات اصلی را تغییر بدیم ، هیچ تأثیری در عنصر کپی شده نخواهد داشت. رشته ها،اعداد و boolean از این نوع کپی هستن.
const original = 'Marina';
let copy = original ; //Marina
copy = 'Magdy';
console.log(original); //Marina
console.log(copy); //Magdy
اما توی کپی سطحی یا shallow copy وقتی یه کپی ایجاد می کنیم در حقیقت یک نسخه جدید ایجاد کردیم که به نسخه اصلی متصل هستش.بنابراین اگر عنصر اصلی را تغییر بدیم ، بر یک مورد کپی شده نیز تأثیر خودش ایجاد میکنه و تغییر می کنه اگر عنصر کپی شده تغییر بدیم، در نسخه اصلی تغییر پیدا میشه.
طرف صحبت من دردسرهایی هستش که shallow copy ایجاد می کنن و دو تا هم بیشتر نیستن یکی object اون یکی Array list ها هستن.
const car1 = {color : "red" , wheels : 4};
let car2 = car1;
car2.color = "black"
console.log(car1.color);//black
console.log(car2.color);//black
همین طوری که در این مثال دیدید تغییر در کپی باعث تاثیر در متغیر اصلی شدش. اما بریم سراغ راه حل :
Objects
روش اول: استفاده از اپراتور های spread
const car1 = {color : "red" , wheels : 4};
let car2 = {...car1};
car2.color = "black"
console.log(car1.color);//red
console.log(car2.color);//black
روش دوم: استفاده از دستور Object.assign :
const car1 = {color : "red" , wheels : 4};
let car2 = Object.assign({}, car1);
car2.color = "black"
console.log(car1.color);//red
console.log(car2.color);//black
روش سوم: استفاده از دستور JSON.parse() & JSON.stringify() :
const car1 = {color : "red" , wheels : 4};
let car2 = JSON.parse(JSON.stringify(car1));
car2.color = "black"
console.log(car1.color);//red
console.log(car2.color);//black
به کمک این سه روش ما تونستیم یه متغیر بدون اینکه باعث تغییر در متغیر اصلی که از نوع object باشه ، کپی کنیم.
حالا بریم سراغ کپی کردن برای آرایه ها
Arrays
روش اول: استفاده از اپراتور های spread
const carsOriginal = ["Audi" , "BMW" , "Toyota"];
let carsCopy = [...carsOriginal];
carsCopy[2] = "Kia"
console.log(carsCopy[2]);//Kia
console.log(carsOriginal[2]);//Toyota
روش دوم: استفاده از دستور map, filter, reduce :
const carsOriginal = ["Audi" , "BMW" , "Toyota"];
let carsCopy = carsOriginal.map(car => car);
carsCopy[2] = "Kia"
console.log(carsCopy[2]);//Kia
console.log(carsOriginal[2]);//Toyota
روش سوم: استفاده از دستور JSON.parse() & JSON.stringify() :
const carsOriginal = ["Audi" , "BMW" , "Toyota"];
let carsCopy = JSON.parse(JSON.stringify(carsOriginal));
carsCopy[2] = "Kia"
console.log(carsCopy[2]);//Kia
console.log(carsOriginal[2]);//Toyota
خب به پایان این مقاله رسیدیم ، امیدوارم از این مقاله استفاده کافی ببرید و کمکی باشه برای یادگیری بهتر برنامه نویسی.
ممنون از توجهتون :)
مطلبی دیگر از این انتشارات
چگونه از AJAX برای بارگذاری فایل استفاده می کنید ؟
مطلبی دیگر از این انتشارات
تفاوت Arrow فانکشن ها و توابع معمولی در جاوااسکریپت - بخش دوم
مطلبی دیگر از این انتشارات
10 ترفند کمکی برای کوتاه کردن کدهای جاوا اسکریپتی