JavaScript'ning Object.assign va spread operatorini ob'ektni boshqarish uchun batafsil solishtirish, shu jumladan unumdorlik mezonlari va amaliy foydalanish misollari.
JavaScript Object.assign va Spread: Ishlash unumdorligini taqqoslash va foydalanish holatlari
JavaScript ob'ektlarni boshqarishning bir nechta usullarini taklif etadi. Ikkita keng tarqalgan usul - Object.assign()
va spread operatori (...
). Ikkalasi ham sizga bir yoki bir nechta manba ob'ektlaridan xususiyatlarni maqsad ob'ektiga nusxalashga imkon beradi. Biroq, ular sintaksis, ishlash va asosiy mexanizmlarda farq qiladi. Ushbu maqola sizga o'ziga xos foydalanish holati uchun to'g'ri vositani tanlashga yordam beradigan keng qamrovli taqqoslashni taqdim etadi.
Object.assign() ni tushunish
Object.assign()
- bu bir yoki bir nechta manba ob'ektlaridan barcha sanaladigan o'z xususiyatlarini maqsad ob'ektiga nusxalovchi usul. U maqsad ob'ektini to'g'ridan-to'g'ri o'zgartiradi va uni qaytaradi. Asosiy sintaksis quyidagicha:
Object.assign(target, ...sources)
target
: Xususiyatlar nusxalanadigan maqsad ob'ekti. Ushbu ob'ekt o'zgartiriladi.sources
: Xususiyatlar nusxalanadigan bir yoki bir nechta manba ob'ektlari.
Misol:
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target); // Output: { a: 1, b: 4, c: 5 }
console.log(returnedTarget === target); // Output: true
Ushbu misolda source
xususiyatlari target
ga nusxalanadi. b
xususiyati o'zgarishi va returnedTarget
ning target
bilan bir xil ekanligiga e'tibor bering.
Spread Operatorini tushunish
Spread operatori (...
) iterable (massiv yoki ob'ekt kabi) ni alohida elementlarga kengaytirishga imkon beradi. Ob'ektlar bilan foydalanilganda, u ob'ektning xususiyatlarining sayoz nusxasini yangi ob'ektga yaratadi. Sintaksis oddiy:
const newObject = { ...sourceObject };
Misol:
const source = { a: 1, b: 2 };
const newObject = { ...source };
console.log(newObject); // Output: { a: 1, b: 2 }
console.log(newObject === source); // Output: false
Bu yerda, newObject
source
xususiyatlarining nusxasini o'z ichiga oladi. Muhimi, newObject
source
dan farq qiluvchi *yangi* ob'ekt hisoblanadi.
Asosiy farqlar
Ikkala Object.assign()
va spread operatori o'xshash natijalarga erishsa-da (ob'ekt xususiyatlarini nusxalash), ular muhim farqlarga ega:
- O'zgaruvchanlik: Spread operatori yangi ob'ekt yaratadi va asl ob'ektni o'zgarishsiz qoldiradi (o'zgarmas).
Object.assign()
maqsad ob'ektini to'g'ridan-to'g'ri o'zgartiradi (o'zgaruvchan). - Maqsad ob'ektini boshqarish:
Object.assign()
sizga maqsad ob'ektini belgilashga imkon beradi, spread operatori esa har doim yangisini yaratadi. - Xususiyatlarning sanalishi: Ikkala usul ham sanaladigan xususiyatlarni nusxalaydi. Sanalmaydigan xususiyatlar nusxalanmaydi.
- Meriy xususiyatlar: Hech bir usul prototip zanjiridan meros bo'lib qolgan xususiyatlarni nusxalamaydi.
- Setterlar:
Object.assign()
maqsad ob'ektida setterlarni chaqiradi. Spread operatori chaqirmaydi; u qiymatlarni to'g'ridan-to'g'ri tayinlaydi. - Noma'lum yoki Null manbalari:
Object.assign()
null
vaundefined
manba ob'ektlarini o'tkazib yuboradi.null
yokiundefined
tarqatish xato chiqaradi.
Ishlashni taqqoslash
Ayniqsa, katta ob'ektlar yoki tez-tez operatsiyalar bilan ishlaganda ishlash muhim ahamiyatga ega. Mikrobenchmarks doimiy ravishda spread operatori Object.assign()
ga qaraganda tezroq ekanligini ko'rsatadi. Farq ularning asosiy amalga oshirilishidan kelib chiqadi.
Nima uchun Spread Operatori tezroq?
Spread operatori ko'pincha JavaScript dvigatellarida optimallashtirilgan ichki implementatsiyalardan foyda oladi. U ob'ekt va massiv yaratish uchun maxsus mo'ljallangan bo'lib, dvigatellarga Object.assign()
bilan mumkin bo'lmagan optimallashtirishlarni amalga oshirishga imkon beradi. Object.assign()
setterlar va turli xil xususiyat tavsifnomalari kabi turli holatlarni hal qilishi kerak, bu uni o'z-o'zidan murakkablashtiradi.
Benchmark namunasi (ko'rsatkich):
// Soddalashtirilgan misol (haqiqiy benchmarklar ko'proq iteratsiyalarni va mustahkam sinovlarni talab qiladi)
const object1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
const object2 = { f: 6, g: 7, h: 8, i: 9, j: 10 };
// Object.assign() yordamida
console.time('Object.assign');
for (let i = 0; i < 1000000; i++) {
Object.assign({}, object1, object2);
}
console.timeEnd('Object.assign');
// Spread Operator yordamida
console.time('Spread Operator');
for (let i = 0; i < 1000000; i++) {
({...object1, ...object2 });
}
console.timeEnd('Spread Operator');
Eslatma: Bu ko'rsatish maqsadida oddiy misoldir. Haqiqiy benchmarklar aniq va ishonchli natijalar uchun maxsus benchmarking kutubxonalaridan (masalan, Benchmark.js) foydalanishi kerak. Ishlash farqining kattaligi JavaScript dvigateliga, ob'ektning o'lchamiga va bajarilayotgan maxsus operatsiyalarga qarab farq qilishi mumkin.
Foydalanish holatlari: Object.assign()
Spread operatorining ishlash afzalliklariga qaramay, Object.assign()
muayyan holatlarda qimmatlidir:
- Mavjud ob'ektni o'zgartirish: Agar siz joyida ob'ektni yangilashingiz kerak bo'lsa (mutatsiya) yangisini yaratishdan ko'ra. Bu o'zgaruvchan holatni boshqarish kutubxonalari bilan ishlaganda yoki ishlash juda muhim bo'lsa va siz yangi ob'ekt ajratishni oldini olishga arziydiganligini tasdiqlash uchun kodni profil qilsangiz, odatiy holdir.
- Bir nechta ob'ektlarni yagona maqsadga birlashtirish:
Object.assign()
bir nechta manba ob'ektlaridan xususiyatlarni bitta maqsadga samarali birlashtira oladi. - Eski JavaScript muhitlari bilan ishlash: Spread operatori ES6 xususiyatidir. Agar siz eski brauzerlar yoki ES6 ni qo'llab-quvvatlamaydigan muhitlarni qo'llab-quvvatlashingiz kerak bo'lsa,
Object.assign()
mos keladigan alternativani taqdim etadi (garchi siz uni polyfill qilishingiz kerak bo'lishi mumkin). - Setterlarni chaqirish: Agar siz xususiyatni tayinlash paytida maqsad ob'ektida belgilangan setterlarni ishga tushirishingiz kerak bo'lsa,
Object.assign()
to'g'ri tanlovdir.
Misol: O'zgaruvchan usulda holatni yangilash
let state = { name: 'Alice', age: 30 };
function updateName(newName) {
Object.assign(state, { name: newName }); // 'state' ob'ektini o'zgartiradi
}
updateName('Bob');
console.log(state); // Output: { name: 'Bob', age: 30 }
Foydalanish holatlari: Spread Operatori
Spread operatori odatda ko'pgina zamonaviy JavaScript ishlab chiqishda o'zgaruvchanlik va ishlash afzalliklari uchun afzal ko'riladi:
- Mavjud xususiyatlar bilan yangi ob'ektlarni yaratish: Boshqa ob'ektdan xususiyatlarning nusxasi bilan yangi ob'ekt yaratmoqchi bo'lsangiz, ko'pincha ba'zi o'zgartirishlar bilan.
- Funktsional dasturlash: Spread operatori funktsional dasturlash tamoyillariga yaxshi mos keladi, bu o'zgaruvchanlikka va yon ta'sirlarni oldini olishga urg'u beradi.
- React holatini yangilash: React da spread operatori komponent holatini o'zgarmas tarzda yangilashda yangi holat ob'ektlarini yaratish uchun keng tarqalgan.
- Redux Reducerlari: Redux reducerlari ko'pincha harakatlarga asoslangan yangi holat ob'ektlarini qaytarish uchun spread operatoridan foydalanadi.
Misol: React holatini o'zgarmas tarzda yangilash
import React, { useState } from 'react';
function MyComponent() {
const [state, setState] = useState({ name: 'Charlie', age: 35 });
const updateAge = (newAge) => {
setState({ ...state, age: newAge }); // Yangi holat ob'ektini yaratadi
};
return (
<div>
<p>Name: {state.name}</p>
<p>Age: {state.age}</p>
<button onClick={() => updateAge(36)}>Yoshni oshirish</button>
</div>
);
}
export default MyComponent;
Sayoz nusxa va Chuqur nusxa
Shuni tushunish muhimki, Object.assign()
ham, spread operatori ham *sayoz* nusxa bajaradi. Bu faqat yuqori darajadagi xususiyatlar nusxalanishini anglatadi. Agar ob'ekt ichki ob'ektlar yoki massivlarni o'z ichiga olsa, faqat o'sha ichki tuzilmalarga havola nusxalanadi, ichki tuzilmalarning o'zlari emas.
Sayoz nusxa misoli:
const original = { a: 1, b: { c: 2 } };
const copy = { ...original };
copy.a = 3; // 'copy.a' ni o'zgartiradi, lekin 'original.a' o'zgarishsiz qoladi
copy.b.c = 4; // 'original.b.c' ni o'zgartiradi, chunki 'copy.b' va 'original.b' bir xil ob'ektga ishora qiladi
console.log(original); // Output: { a: 1, b: { c: 4 } }
console.log(copy); // Output: { a: 3, b: { c: 4 } }
*Chuqur* nusxa yaratish uchun (ichki ob'ektlar ham nusxalanadigan joyda) siz quyidagi texnikalardan foydalanishingiz kerak:
JSON.parse(JSON.stringify(object))
: Bu oddiy, ammo potentsial sekin usul. U funksiyalar, sanalar yoki aylanma havolalar bilan ishlamaydi.- Lodash's
_.cloneDeep()
: Lodash kutubxonasi tomonidan taqdim etilgan yordamchi funksiya. - Maxsus rekursiv funktsiya: Murakkabroq, lekin chuqur nusxalash jarayonini eng ko'p boshqarishni ta'minlaydi.
- Strukturaviy klon: Ob'ektlarni chuqur nusxalash uchun brauzerlar uchun
window.structuredClone()
yoki Node.js uchunstructuredClone
paketidan foydalanadi.
Eng yaxshi amaliyotlar
- O'zgaruvchanlik uchun Spread Operatorini tanlang: Ko'pgina zamonaviy JavaScript ilovalarida, yangi ob'ektlarni o'zgarmas tarzda yaratish uchun spread operatorini afzal ko'ring, ayniqsa holatni boshqarish yoki funktsional dasturlash bilan ishlaganda.
- Mavjud ob'ektlarni o'zgartirish uchun Object.assign() dan foydalaning: Agar sizga mavjud ob'ektni joyida o'zgartirish kerak bo'lsa, ayniqsa
Object.assign()
ni tanlang. - Sayoz va Chuqur nusxani tushuning: Ikkala usul ham sayoz nusxa bajarishini biling. Zarur bo'lganda chuqur nusxalash uchun tegishli texnikalardan foydalaning.
- Unumdorlik muhim bo'lganda benchmarkni qo'llang: Agar ishlash muhim bo'lsa, o'ziga xos foydalanish holatida
Object.assign()
va spread operatorining ishlashini taqqoslash uchun sinchkov benchmarklarni o'tkazing. - Kodning o'qilishini ko'rib chiqing: Jamoangiz uchun eng o'qiladigan va saqlanib qoladigan kodga olib keladigan usulni tanlang.
Xalqaro e'tiborga olish
Object.assign()
va spread operatorining xatti-harakati butun dunyo bo'ylab turli JavaScript muhitlarida odatda izchil bo'ladi. Biroq, quyidagi potentsial jihatlarga e'tibor berish kerak:
- Belgilar kodlash: Kodningiz belgilarning kodlanishini to'g'ri boshqarishini ta'minlang, ayniqsa turli tillardan belgilar o'z ichiga olgan satrlar bilan ishlashda. Ikkala usul ham satr xususiyatlarini to'g'ri nusxalaydi, ammo ushbu satrlarni qayta ishlash yoki ko'rsatishda kodlash masalalari paydo bo'lishi mumkin.
- Sana va vaqt formatlari: Sanalarni o'z ichiga olgan ob'ektlarni nusxalashda vaqt zonalari va sana formatlariga e'tibor bering. Agar siz sanalarni ketma-ketlashtirishingiz yoki deseriallashtirishingiz kerak bo'lsa, turli mintaqalarda izchillikni ta'minlash uchun tegishli usullardan foydalaning.
- Raqamlarni formatlash: Turli mintaqalar raqamlarni formatlash uchun turli konventsiyalardan foydalanadilar (masalan, o'nli ajratgichlar, minglab ajratgichlar). Turli joylardagi foydalanuvchilarga ko'rsatilishi mumkin bo'lgan raqamli ma'lumotlarni o'z ichiga olgan ob'ektlarni nusxalash yoki boshqarishda ushbu farqlardan xabardor bo'ling.
Xulosa
Object.assign()
va spread operatori JavaScript da ob'ektlarni boshqarish uchun qimmatli vositalardir. Spread operatori odatda yaxshi ishlashni taklif etadi va o'zgaruvchanlikni targ'ib qiladi, bu uni ko'plab zamonaviy JavaScript ilovalarida afzal tanlov qiladi. Biroq, Object.assign()
mavjud ob'ektlarni o'zgartirish va eski muhitlarni qo'llab-quvvatlash uchun foydalidir. Ularning farqlari va foydalanish holatlarini tushunish yanada samarali, saqlanib qolinadigan va mustahkam JavaScript kodini yozishga yordam beradi.