تفاوت در کپی سطحی و کپی عمقی در جاوا اسکریپت

خیلی وقتا برامون پیش اومده که یه خواستیم یه متغیر کپی کنیم توی یه متغیر دیگه.فرض کنید این متغیر ما از نوع 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 : &quotred&quot , wheels : 4};
let car2 = car1;
car2.color = &quotblack"
console.log(car1.color);//black
console.log(car2.color);//black

همین طوری که در این مثال دیدید تغییر در کپی باعث تاثیر در متغیر اصلی شدش. اما بریم سراغ راه حل :

Objects

روش اول: استفاده از اپراتور های spread

const car1 = {color : &quotred&quot , wheels : 4};
let car2 = {...car1};
car2.color = &quotblack"
console.log(car1.color);//red
console.log(car2.color);//black

روش دوم: استفاده از دستور Object.assign :

const car1 = {color : &quotred&quot , wheels : 4};
let car2 = Object.assign({}, car1);
car2.color = &quotblack"
console.log(car1.color);//red
console.log(car2.color);//black

روش سوم: استفاده از دستور JSON.parse() & JSON.stringify() :

const car1 = {color : &quotred&quot , wheels : 4};
let car2 = JSON.parse(JSON.stringify(car1));
car2.color = &quotblack"
console.log(car1.color);//red
console.log(car2.color);//black

به کمک این سه روش ما تونستیم یه متغیر بدون اینکه باعث تغییر در متغیر اصلی که از نوع object باشه ، کپی کنیم.

حالا بریم سراغ کپی کردن برای آرایه ها

Arrays

روش اول: استفاده از اپراتور های spread

const carsOriginal = [&quotAudi&quot , &quotBMW&quot , &quotToyota&quot];
let carsCopy = [...carsOriginal];
carsCopy[2] = &quotKia&quot
console.log(carsCopy[2]);//Kia
console.log(carsOriginal[2]);//Toyota

روش دوم: استفاده از دستور map, filter, reduce :

const carsOriginal = [&quotAudi&quot , &quotBMW&quot , &quotToyota&quot];
let carsCopy = carsOriginal.map(car => car);
carsCopy[2] = &quotKia&quot
console.log(carsCopy[2]);//Kia
console.log(carsOriginal[2]);//Toyota

روش سوم: استفاده از دستور JSON.parse() & JSON.stringify() :

const carsOriginal = [&quotAudi&quot , &quotBMW&quot , &quotToyota&quot];
let carsCopy = JSON.parse(JSON.stringify(carsOriginal));
carsCopy[2] = &quotKia&quot
console.log(carsCopy[2]);//Kia
console.log(carsOriginal[2]);//Toyota



خب به پایان این مقاله رسیدیم ، امیدوارم از این مقاله استفاده کافی ببرید و کمکی باشه برای یادگیری بهتر برنامه نویسی.

ممنون از توجهتون :)