درود دوستان مشکل عجیبی که در جاوااسکریپت برخوردم اینه که من یک global array دارم و به یک تابعی ارسال میکنم و داخل اون تابع من انتظار دارم که هر بلایی سر اون آرایه بیارم داخل تابع بمونه و در آرایه اصلی هیچ تغییری صورت نگیره واقعا دلیل این کار قابل درک نیست برام
let a = []
function printA(item) {
console.log(item)
}
function changeA(arr) {
let newArr = arr
newArr.push('abc')
}
changeA(a)
printA(a)
بخاطر اینکه شما داری یک کپی می گیری با تمام خاصیت ها و اینکه بندازیش تو یک متغیر دیگه مثل زبان های دیگه js کار نمی کنه باید زحمت بکشی ازش با spread اوپرتور یک کپی بگیری
مثلا
let newArry = [...ar]
می تونی آرایه رو یک بار جی سان استرینگفای کنی بندازی داخل یک متغیر
روش دیگه هم مثلا برای آبجکت ها
const copy = array.map(object => ({ ...object }))
شما اگر اون رو بندازی داخل یک متغیر داری ریفرنسشم کپی می کنی بخاطر همین اون newArray تغییر کنه آرایه اصلی a هم تغییر می کنه
درود توماج جان سال نو مبارک. باعث افتخار هستم اساتید و دوستان رو اینجا می بینیم
فکر کنم اونجوری که داخل mdn نوشته assign نمی یاد deep clone بکنه و پراپرتی هارو هم می یاره و ریفرنس رو کپی می کنه
For deep cloning, we need to use alternatives, because Object.assign() copies property values.
If the source value is a reference to an object, it only copies the reference value.
تابع زیر هم هست که مخصوص اینکار هست ولی من برای لیست استفاده نکردمش
که چندین لایه تو در تو هم باشه آبجکت بازم کلون رو کامل می گیره کاری که اسپرید اوپروتور داخلش مشکل داره
structuredClone(obj) و JSON.parse(JSON.stringify(obj)) خوب deep clone میکنن
و الان چون حس ناامنی بهم میده قصد دارم در کل پروژه هرچی تابع و متد دارم اولش با یکی از روش ها همه وروردی ها رو deep clone کنم و بنوعی default همه توابع باشه. ولی مثل اینکه مردم با این مورد مشکلی ندارن چون سورس کدهایی که دیدم از این مورد ها اصلا استفاده نکردن برای امینت کدهاشون.
آپدیت: با Object.freeze هم میشه یک immutable array ساخت: (البته برای deep کردن قضیه باید از forEach و شرط استفاده کرد )
let a = deepClone([])
function printA(item) {
console.log(item)
}
function changeA(arr) {
let newArr = [...arr]
return newArr.push('abc')
}
changeA(a)
printA(a)
function deepClone(obj) {
Object.values(obj).forEach((value) => {
if (value && typeof value === 'object') {
deepClone(value)
}
})
return Object.freeze(obj)
}