Katakanlah saya punya options
variabel dan saya ingin menetapkan beberapa nilai default.
Apa manfaat / kelemahan dari dua alternatif ini?
Menggunakan objek menyebar
options = {...optionsDefault, ...options};
Atau menggunakan Object.assign
options = Object.assign({}, optionsDefault, options);
Ini adalah komitmen yang membuat saya bertanya-tanya.
javascript
ecmascript-6
Olivier Tassinari
sumber
sumber
Jawaban:
Ini belum tentu lengkap.
Sebarkan sintaks
Keuntungan:
Jika membuat kode untuk dieksekusi di lingkungan tanpa dukungan asli, Anda mungkin bisa mengkompilasi sintaks ini (bukan menggunakan polyfill). (Dengan Babel, misalnya.)
Kurang bertele-tele.
Kekurangan:
Ketika jawaban ini awalnya ditulis, ini adalah proposal , bukan standar. Saat menggunakan proposal pertimbangkan apa yang akan Anda lakukan jika Anda menulis kode dengannya sekarang dan itu tidak mendapatkan standar atau perubahan saat bergerak menuju standardisasi. Sejak ini telah distandarisasi dalam ES2018.
Secara literal, tidak dinamis.
Object.assign()
Keuntungan:
Standar
Dinamis. Contoh:
Kekurangan:
Itu tidak terkait langsung dengan apa yang Anda minta. Kode itu tidak menggunakan
Object.assign()
, itu menggunakan kode pengguna (object-assign
) yang melakukan hal yang sama. Mereka tampaknya mengkompilasi kode itu dengan Babel (dan menggabungkannya dengan Webpack), yang saya bicarakan: sintaks yang bisa Anda kompilasi. Mereka tampaknya lebih suka daripada harus dimasukkanobject-assign
sebagai ketergantungan yang akan masuk ke gedung mereka.sumber
Object.assign()
. Atau Anda bisa secara manual mengulangi lebih dari satu array objek dan props mereka sendiri secara manual menugaskan mereka ke target dan membuatnya lebih verbose: PUntuk objek referensi istirahat / spread diselesaikan dalam ECMAScript 2018 sebagai tahap 4. Proposal dapat ditemukan di sini .
Untuk sebagian besar objek reset dan spread bekerja dengan cara yang sama, perbedaan utama adalah bahwa spread mendefinisikan properti, sementara Object.assign () menyetelnya . Ini berarti Object.assign () memicu setter.
Perlu diingat bahwa selain ini, objek rest / spread 1: 1 memetakan ke Object.assign () dan bertindak berbeda terhadap array (iterable) spread. Misalnya, ketika menyebarkan nilai null array tersebar. Namun menggunakan objek, menyebarkan nilai nol secara diam-diam menyebar ke apa-apa.
Array (Iterable) Sebarkan Contoh
Contoh Penyebaran Objek
Ini konsisten dengan cara kerja Object.assign (), keduanya diam-diam mengecualikan nilai nol tanpa kesalahan.
sumber
Object.assign
menggunakan setter.Object.assign({set a(v){this.b=v}, b:2}, {a:4}); // {b: 4}
vs.{...{set a(v){this.b=v}, b:2}, ...{a:4}}; // {a: 4, b: 2}
const x = {c: null};
. Dalam hal ini, AFAIK, kita akan melihat perilaku seperti array://{a: 1, b: 2, c: null}
.Saya pikir satu perbedaan besar antara operator spread dan
Object.assign
yang tampaknya tidak disebutkan dalam jawaban saat ini adalah bahwa operator spread tidak akan menyalin prototipe objek sumber ke objek target. Jika Anda ingin menambahkan properti ke objek dan Anda tidak ingin mengubah instance itu, maka Anda harus menggunakannyaObject.assign
. Contoh di bawah ini harus menunjukkan ini:sumber
errorExtendedUsingAssign === error
,, tetapierrorExtendedUsingSpread
objek baru (dan prototipe tidak disalin).let target = Object.create(source); Object.assign(target, source);
Seperti yang telah disebutkan orang lain, pada saat penulisan ini,
Object.assign()
membutuhkan polyfill dan penyebaran objek...
memerlukan beberapa pengubahan (dan mungkin juga polyfill) agar dapat bekerja.Pertimbangkan kode ini:
Keduanya menghasilkan output yang sama.
Ini adalah output dari Babel, ke ES5:
Ini pemahaman saya sejauh ini.
Object.assign()
sebenarnya standar, sedangkan objek...
belum menyebar . Satu-satunya masalah adalah dukungan browser untuk yang pertama dan di masa depan, yang terakhir juga.Mainkan dengan kode di sini
Semoga ini membantu.
sumber
{}
harus memperbaiki ketidakkonsistenan.Operator penyebaran objek (...) tidak berfungsi di browser, karena itu belum menjadi bagian dari spesifikasi ES apa pun, hanya proposal. Satu-satunya pilihan adalah mengkompilasinya dengan Babel (atau yang serupa).
Seperti yang Anda lihat, itu hanya gula sintaksis di atas Object.assign ({}).
Sejauh yang saya bisa lihat, ini adalah perbedaan penting.
...
untuk objek tidak terstandarisasi...
melindungi Anda dari secara tidak sengaja bermutasi objek...
akan melakukan polyfill Object.assign di browser tanpa itu...
membutuhkan lebih sedikit kode untuk mengekspresikan ide yang samasumber
Object.assign
, karena operator spread akan selalu memberi Anda objek baru.Saya ingin merangkum status fitur ES "spread object merge", di browser, dan di ekosistem melalui alat.
Spec
Browser: di Chrome, di SF, Firefox segera (ver 60, IIUC)
Alat: Node 8.7, TS 2.1
Tautan
Contoh Kode (berfungsi ganda sebagai uji kompatibilitas)
Lagi: Pada saat penulisan, sampel ini berfungsi tanpa transpilasi di Chrome (60+), Edisi Pengembang Firefox (preview Firefox 60), dan Node (8.7+).
Mengapa Menjawab
Saya menulis ini 2,5 tahun setelah pertanyaan awal. Tetapi saya memiliki pertanyaan yang sama, dan di sinilah Google mengirim saya. Saya seorang budak misi SO untuk memperbaiki ekor panjang.
Karena ini merupakan perluasan dari sintaks "array spread", saya merasa sangat sulit untuk google, dan sulit ditemukan di tabel kompatibilitas. Yang paling dekat yang bisa saya temukan adalah Kangax "sebaran properti" , tetapi tes itu tidak memiliki dua spread dalam ekspresi yang sama (bukan gabungan). Juga, nama dalam halaman status proposal / konsep / browser semua menggunakan "sebaran properti", tetapi bagi saya sepertinya itu adalah "prinsipal pertama" yang diterima komunitas setelah proposal untuk menggunakan sintaksis spread untuk "penggabungan objek". (Yang mungkin menjelaskan mengapa sangat sulit untuk google.) Jadi saya mendokumentasikan temuan saya di sini sehingga orang lain dapat melihat, memperbarui, dan menyusun tautan tentang fitur spesifik ini. Saya harap ini berhasil. Tolong bantu sebarkan berita itu mendarat di spec dan di browser.
Terakhir, saya akan menambahkan info ini sebagai komentar, tetapi saya tidak dapat mengeditnya tanpa melanggar maksud asli penulis. Secara khusus, saya tidak dapat mengedit komentar @ ChillyPenguin tanpa kehilangan niatnya untuk memperbaiki @RichardSchulte. Tetapi bertahun-tahun kemudian Richard ternyata benar (menurut saya). Jadi saya menulis jawaban ini sebagai gantinya, berharap akan mendapatkan daya tarik pada jawaban lama pada akhirnya (mungkin butuh bertahun-tahun, tapi itulah efek dari long tail , setelah semua).
sumber
CATATAN: Spread BUKAN hanya gula sintaksis di sekitar Object.assign. Mereka beroperasi jauh berbeda di belakang layar.
Object.assign menerapkan setter ke objek baru, Spread tidak. Selain itu, objek tersebut harus dapat diubah.
Salin Gunakan ini jika Anda memerlukan nilai objek seperti saat ini, dan Anda tidak ingin nilai mencerminkan perubahan yang dibuat oleh pemilik objek lain.
Gunakan untuk membuat salinan dangkal objek praktik yang baik untuk selalu menetapkan properti yang tidak dapat diubah untuk disalin - karena versi yang dapat diubah dapat dipindahkan ke properti yang tidak dapat diubah, salinan akan memastikan bahwa Anda akan selalu berurusan dengan objek yang tidak dapat diubah
Tetapkan Tetapkan agak berlawanan dengan menyalin. Tetapkan akan menghasilkan setter yang memberikan nilai ke variabel instan secara langsung, daripada menyalin atau mempertahankannya. Saat memanggil pengambil properti penetapan, ia mengembalikan referensi ke data aktual.
sumber
Jawaban lain sudah tua, tidak bisa mendapat jawaban yang baik.
Contoh di bawah ini adalah untuk objek literal, membantu bagaimana keduanya dapat saling melengkapi, dan bagaimana keduanya tidak dapat saling melengkapi (oleh karena itu perbedaan):
Beberapa contoh kecil lainnya di sini, juga untuk array & objek:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
sumber
Ini sekarang bagian dari ES6, dengan demikian distandarisasi, dan juga didokumentasikan di MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
Ini sangat nyaman untuk digunakan dan membuat banyak akal bersama perusakan objek.
Satu kelebihan yang tersisa yang tercantum di atas adalah kemampuan dinamis Object.assign (), namun ini semudah menyebarkan array di dalam objek literal. Dalam output babel yang dikompilasi, ia menggunakan apa yang ditunjukkan dengan Object.assign ()
Jadi jawaban yang benar adalah dengan menggunakan objek menyebar karena sekarang distandarisasi, banyak digunakan (lihat bereaksi, redux, dll), mudah digunakan, dan memiliki semua fitur Object.assign ()
sumber
Saya ingin menambahkan contoh sederhana ini ketika Anda harus menggunakan Object.assign.
Tidak jelas saat Anda menggunakan JavaScript. Tetapi dengan TypeScript lebih mudah jika Anda ingin membuat instance dari beberapa kelas
sumber