کپی سطحی در مقابل کپی عمیق در JavaScript

JavaScript بسته به نوع داده، کپی کردن را به دو روش انجام می‌دهد.

مقادیر اولیه (کپی بر اساس مقدار) انواع اولیه شامل strings، numbers، booleans، symbols، bigInt و null هستند. وقتی یک مقدار اولیه را کپی می‌کنید، JavaScript یک نسخه مستقل و جدید در حافظه ایجاد می‌کند.

مثال:

let a = 10;
let b = a;
b = 20;

نتیجه: a همچنان 10 باقی می‌ماند.

مقادیر غیراولیه (کپی بر اساس ارجاع) اشیاء (Objects) و آرایه‌ها متفاوت عمل می‌کنند. آن‌ها از ارجاع (references) استفاده می‌کنند. وقتی یک شیء را کپی می‌کنید، شما فقط اشاره‌گر (pointer) به مکان آن در حافظه را کپی می‌کنید.

مثال:

let original = { name: "YOO" };
let copy = original;
copy.name = "NEW";

نتیجه: مقدار original.name اکنون "NEW" است.

تفاوت: سطحی در مقابل عمیق

یک کپی سطحی (Shallow copy)، سطح اول یک شیء را کپی می‌کند. اگر شیء دارای اشیاء تودرتو (nested objects) باشد، همچنان به همان ارجاعات تودرتوی اصلی اشاره می‌کند. یک کپی عمیق (Deep copy)، یک شیء کاملاً جدید با تمام مقادیر جدید ایجاد می‌کند.

آن را مانند پیتزا تصور کنید:

  • کپی سطحی: شما و دوستتان یک پیتزا را با هم تقسیم می‌کنید. اگر دوستتان یک برش بخورد، پیتزا برای شما هم کوچک‌تر می‌شود.
  • کپی عمیق: هر دوی شما پیتزاهای جداگانه خود را دارید. اگر دوستتان یک برش بخورد، پیتزای شما تغییری نمی‌کند.

روش کپی سطحی می‌توانید از عملگر spread (...) برای ایجاد یک کپی سطحی استفاده کنید.

let original = { name: "YOO", details: { age: 22 } };
let copy = { ...original };

هشدار: اگر original.details.age را تغییر دهید، copy.details.age نیز تغییر می‌کند. این همان تله‌ی کپی سطحی است.

روش‌های کپی عمیق

  1. structuredClone() این یک تابع داخلی در مرورگرهای مدرن و Node.js است. این تابع ساختارهای تودرتو را به شکلی عالی مدیریت می‌کند.

مزایا:

  • سریع و بومی (native).
  • Dates، RegExp و Maps را مدیریت می‌کند.

معایب:

  • اگر شیء شامل تابع (function) یا گره‌های DOM باشد، با خطا مواجه می‌شود.
  1. JSON.parse(JSON.stringify()) این یک ترفند قدیمی است که در آن یک شیء را به رشته (string) تبدیل کرده و سپس دوباره به شیء تبدیل می‌کنید.

چرا باید از آن اجتناب کرد:

  • داده‌هایی مانند undefined، Map، Set یا Infinity را از دست می‌دهد.
  • می‌تواند باعث خراب شدن مقادیر خاص شود.

منبع: https://dev.to/yogesh_992/shallow-copy-vs-deep-copy-in-java-script-explained-in-easiest-way-3dg5