Moment: jadikan momen sebagian besar tidak berubah

Dibuat pada 3 Jul 2014  ·  163Komentar  ·  Sumber: moment/moment

Ada banyak diskusi tentang ini. Berikut proposalnya:

Metode yang dapat berubah berikut akan menjadi tidak dapat diubah dalam 3.0.0: utc , local , zone , add , subtract , startOf , endOf , lang , juga di duration : add , subtract , dan lang .

Sebagai permulaan, semua metode akan diduplikasi dengan varian methodNameMute . Kami juga membutuhkan varian yang tidak dapat diubah bernama methodNameImmute . Dari 3.0 metode lama biasa akan mulai menggunakan opsi yang tidak dapat diubah secara default.

Yang diperdebatkan adalah:

  • haruskah lang dibuat tidak berubah
  • haruskah semua getter/setter (termasuk get / set ) dibuat tidak dapat diubah juga
  • penamaan versi metode yang dapat berubah dan tidak dapat diubah
  • dan tentu saja -- haruskah kita beralih, atau berhenti di API yang tidak dapat diubah

Bagian baiknya adalah kita dapat membuat versi metode yang tidak dapat diubah hari ini dan memutuskan apa yang harus dilakukan nanti. Jika kita beralih itu juga berarti cabang 2.x akan ada cukup lama setelah 3.x keluar.

@icambron @timrwood @gregwebs @yang @lfnavess @soswow @langalex

Enhancement

Komentar yang paling membantu

Dua sen saya adalah bahwa kita harus memilih kekekalan penuh atau tidak sama sekali. Memiliki beberapa metode yang tidak dapat diubah ( startOf , add ) dan beberapa tidak ( year , get ) hanya membingungkan, dan pengembang harus melacak yang mana yang mana.

Semua 163 komentar

Dua sen saya adalah bahwa kita harus memilih kekekalan penuh atau tidak sama sekali. Memiliki beberapa metode yang tidak dapat diubah ( startOf , add ) dan beberapa tidak ( year , get ) hanya membingungkan, dan pengembang harus melacak yang mana yang mana.

Saya juga lebih suka semuanya tidak berubah secara default. Apakah getter sudah tidak berubah?

Berikut adalah masalah besar yang saya lihat dengan beralih ke kekekalan.

Kekekalan Semu

Karena sifat javascript, kita tidak akan pernah bisa memiliki kekekalan sejati.

Yang terbaik yang bisa kita lakukan adalah membuat salinan dan kemudian bermutasi dan mengembalikan salinan itu. Kami dapat dengan hati-hati membungkus semua metode publik untuk memastikan kami selalu menyalin dan bermutasi daripada hanya bermutasi, tetapi itu tidak mencegah seseorang melakukan m._d = new Date() atau bahkan m._d.setHours(1) .

Saya setuju dengan @icambron , jika kita pindah ke kekekalan, itu harus menjadi perubahan total. Metode apa pun yang mungkin dapat mengubah properti suatu saat akan membuat salinan momen tersebut dan membuat perubahan pada salinannya.

Luas Permukaan Api

Hal yang disayangkan tentang beralih ke pseudo-kekekalan adalah bahwa banyak api baru perlu dibuat jika kita ingin tetap mendukung mutabilitas.

Sebelumnya, beralih dari mengubah momen menjadi mengkloning dan mengubah momen semudah menambahkan .clone() di tempat yang tepat. Sekarang, kita harus membuat antarmuka yang dapat diubah untuk semua setter, yang menambah luas permukaan api secara signifikan.

Ini termasuk ~20 metode penyetel, tambah/kurangi, lokal/utc/zone/tz, startOf/endOf, lang, dan metode lain yang digunakan di plugin pihak ke-3.

Kekhawatiran Memori

Karena kami sekarang membuat salinan setiap kali kami ingin mengubah nilai, penggunaan memori akan meningkat. Tentu saja, momen baru akan mengumpulkan sampah, tetapi biaya tambahan yang terkait dengan perubahan ini adalah sesuatu yang perlu diingat.

Kami harus sangat berhati-hati untuk memastikan kami tidak membuat banyak klon sekali pakai dengan metode yang menggunakan setter lain.

Untuk melacak metode apa yang dipanggil, saya menggunakan pembungkus fungsi kecil ini.

for (var method in moment.fn) {
  moment.fn[method] = (function (fn, method) {
    return function () {
      console.log(method);
      return fn.apply(this, arguments)
    }
  })(moment.fn[method], method)
}

Sekarang, ketika menjalankan suatu metode, kita dapat melihat bagaimana metode lain pada prototipe dapat digunakan. Tidak semua metode ini perlu mengkloning momen, jadi saya menambahkan komentar pada metode yang memerlukan kloning.

moment().isSame(moment(), 'year')
isSame
clone        // clone
startOf      // clone
month        // clone
date         // clone
year         // clone
date         // clone
hours        // clone
minutes      // clone
seconds      // clone
milliseconds // clone
valueOf
local        // clone
zone         // clone
startOf      // clone
month        // clone
date         // clone
year         // clone
date         // clone
hours        // clone
minutes      // clone
seconds      // clone
milliseconds // clone
valueOf

Yaitu 21 eksemplar yang dibuat kemudian langsung dibuang. Jelas kami dapat mengoptimalkan ini dengan menggunakan beberapa metode internal yang dapat berubah dan hanya mengekspos versi yang tidak dapat diubah, tetapi ini akan secara signifikan menambah kompleksitas internal dengan mencoba mencatat momen mana yang masih perlu dikloning dan mana yang tidak.

Kekhawatiran Kinerja

Mengkloning momen jauh lebih lambat daripada mengubah momen. Saya mengumpulkan beberapa tes jsperf untuk ini.

http://jsperf.com/moment-cloning

http://jsperf.com/moment-cloning-2

Saya pikir tes kedua adalah representasi yang jauh lebih baik dari kerugian kinerja saat beralih ke kekekalan semu. Jika kita mengalikan hasil tersebut dengan 21 contoh kloning yang disebutkan di atas, waktu eksekusi jauh lebih lambat.

Saya yakin kami dapat mengoptimalkan jalur untuk mengkloning momen, tetapi kami harus membuatnya 50x lebih cepat agar memiliki kinerja yang sebanding. Saya cukup yakin ini tidak mungkin.

Ringkasan

Beralih ke kekekalan sangat meningkatkan kompleksitas api internal dan eksternal dan memiliki masalah kinerja dan memori utama. Saya tidak berpikir biaya itu sepadan dengan manfaat yang akan diberikan oleh kekekalan.

Saya pikir masalah kinerja yang tercantum di sini tidak ada gunanya:

Secara umum, .clone() awal diperlukan untuk memastikan kebenaran sebelum melakukan mutasi.

Kami tidak dapat berpura-pura seperti clone() tidak diperlukan dengan API saat ini. Kasus utama di sini yang berbeda adalah melakukan beberapa mutasi berurutan. Kasus itu diatasi dengan membuat API pembangun sedemikian rupa sehingga semua mutasi dilakukan sebagai mutasi pada satu klon.

Apakah saya melewatkan kasus penggunaan umum lainnya?

Masalah asli saya adalah tentang metode startOf dan endOf secara khusus. Untuk beberapa alasan, nama-nama ini bagi saya seperti "dapatkan saya memulai sebulan" bukan "mengatur momen ini menjadi awal sebulan". Metode seperti add dan subtract -baik saja dalam hal semantik. Tidak apa-apa untuk Menambahkan sesuatu ke objek tanpa membuat yang baru.
Bagi saya pribadi, mengganti nama metode startOf dan endOf menjadi seperti toStartOf dan toEndOf (seperti "pindahkan momen ini ke awal bulan") akan menyelesaikan masalah isu. Menurut opini saya

@gregwebs Maaf, maksud saya set atas.

Saya tidak setuju dengan @soswow; Saya pikir itu perlu konsisten. Bahkan, saya pikir toStartOf menyiratkan kekekalan bahkan lebih kuat, seperti menyediakan presentasi alternatif ala toISOString . Lebih penting lagi, saya pikir kita harus dapat membuat pernyataan seperti "Penyetel momen mengubah momen" atau "Penyetel momen mengembalikan salinan", bukan "baik, untuk metode ini..."

Tentang kekhawatiran @timrwood :

Bahwa objek JS tidak akan benar-benar tidak berubah tidak mengganggu saya. Intinya adalah bahwa API memberikan kontrak yang tidak dapat diubah. Tentu saja pengguna dapat menipu dengan mengutak-atik properti yang digarisbawahi, dan kecurangan umumnya dimungkinkan bahkan bahasa di mana kekekalan adalah cara utama dalam melakukan sesuatu.

Pada area permukaan dan tentang kinerja: Saya pikir kita perlu menggunakan mutator secara internal untuk menghindari penggunaan semua CPU dan memori itu [1], jadi kita kemudian harus mendukungnya pada tingkat tertentu. Kemudian kita mungkin juga mengekspos mereka secara eksternal, seperti setYear() , dll. Itu menambah banyak area permukaan, tetapi itu tidak benar-benar menambah banyak kerumitan; untuk non-eksplisit-mutator, mengkloning secara eksternal, bermutasi secara internal.

Salah satu cara untuk melihatnya adalah bahwa pengguna harus mengkloning kode mereka, jadi Momen mungkin juga melakukannya untuk mereka. Itu memang menimbulkan masalah dengan rantai di tempat-tempat yang sensitif terhadap kinerja, yang dapat diperangi baik oleh antarmuka pembangun (sesuai ide Greg) atau dengan membiarkan pengguna hanya menggunakan mutator di sana. Pembangun menambahkan banyak kompleksitas [2], jadi saya pikir saya hanya menyukai alternatif mutator eksplisit. Saya pikir kenyataannya adalah bahwa sebagian besar waktu, Momen tidak digunakan dalam situasi sensitif-perf, jadi situasi itu tidak harus menjadi API-bijaksana yang paling nyaman. Saya lebih suka memiliki API abadi yang bagus dengan palka sempurna ketika saya membutuhkannya.

[1] Anak-anak keren di tanah FP menyelesaikan ini dengan _berbagi struktural_, tapi itu mungkin tidak praktis di sini.

[2] Secara tradisional, orang membuat builder yang merupakan objek terpisah, tetapi itu akan sangat bertele-tele di sini, karena Anda harus menyalin seluruh API setter. Hanya meludah, tetapi satu alternatifnya adalah .chain() membuat momen kloning yang hanya memiliki flag isBuilding . Kemudian klon internal diabaikan, hanya mengembalikan objek untuk mutasi. Kemudian build() menghapus flag dan mengembalikan klon itu. Masalahnya adalah Anda membutuhkan getter Anda untuk meneriakkan pembunuhan berdarah jika bendera ditetapkan, atau orang-orang akan berakhir menggunakan Momen yang dirantai tetapi tidak dibangun yang tiba-tiba bermutasi. Maka Anda perlu membedakan secara eksternal dan internal yang disebut getter. pemutih. Alternatif lain adalah secara internal menguraikan fungsionalitas yang dibutuhkan oleh builder ke dalam mixin dan menggunakannya baik di builder dan di Moment, tapi itu mungkin tidak bisa diterapkan dari perspektif kode-organisasi.

apa yang berhasil bagi saya, menambahkan parameter tambahan ke fungsi, sebuah bendera (saya menamai diri sendiri) untuk menunjukkan mutabilitas, secara default tidak dapat diubah (mengembalikan salinan atau objek baru), dan ketika saya mendeteksi kinerja saya menyetel bendera ke true

sudut pandang ini memecahkan banyak konflik,
memiliki fungsi dengan nama yang mirip mengeksekusi kode yang hampir sama,
atau harus mengubah nama fungsi dan mungkin parameternya ketika saya mendeteksi poin kinerja
dalam metode publik saya, saya memulai kode yang memanggil fungsi dengan salinan dan mengikuti panggilan dengan bendera di true
dengan ini saya juga dapat menghubungkan fungsi

dalam kode saya, saya bekerja dengan array array, (seperti tabel, array baris)
jadi saya memiliki fungsi untuk memfilter, menyatukan, dll, yang sebelumnya menjalankan kembali array baru dengan hasil, dan saya mendeteksi bahwa untuk mendapatkan hasil akhir saya memanggil beberapa kali fungsi yang sama, sekarang panggilan pertama adalah membuat salinan dan tidak mengubah array awal, dan panggilan berikut saya bekerja dengan baris menjatuhkan array yang sama yang tidak saya butuhkan

contoh dasar yang mungkin ada di sini:
moment.add = fungsi(ukuran, jumlah, diri){
}

moment.add = fungsi (ukuran, jumlah, diri) {
var $moment = diri ? ini : this.clone();
// kode yang sebenarnya
kembali $momen;
}

Terima kasih semuanya untuk 2 sen mereka :)

Untuk protokolnya, saya setuju dengan postingan terakhir

Ada dua pertanyaan besar yang tersisa.

Yang lebih mudah adalah apa yang seharusnya menjadi API baru, dua opsi:
1.1 metode bernama berbeda (bisa berubah dan tidak berubah) year / setYear , startOf / setStartOf
1.2 atau builder api chain().mutators().build() , yang merupakan versi non- retas dari apa yang diusulkan

Api pembuat jelas terlihat lebih seksi, tetapi harus diperhatikan agar objek tidak bertahan dalam mode pembuatan terlalu lama, yang menambah sumber masalah lain bagi kami dan pengguna.

Sekarang masalah yang sulit -- migrasi ke versi baru. Saya melihat dua opsi di sini:
2.1 pengembang harus menulis ulang kode mereka (regex gila mungkin bekerja di 1.1 dan solusi tingkat AST untuk 1.2 - mengingat tidak ada yang menggunakan year dan month sebagai nama metode mereka sendiri). python mengambil pendekatan ini -- kita semua bisa melihat hasilnya -- bahasa baru telah lahir!
2.2 opsi untuk mengaktifkan builder api selalu (sama seperti sekarang), dan cara menonaktifkannya untuk kode baru. Ini terlihat lebih _evolusi_, tetapi jumlah kebingungan yang ditimbulkannya mungkin tidak sepadan. Setiap momen sekarang memiliki dua flag: apakah itu bisa berubah, dan jika itu - apakah itu benar-benar bisa berubah (tidak ada getter) atau bisa berubah secara transisi (getter ok). Belum lagi menerima objek momen dalam fungsi -- Anda harus memeriksa mode apa, pastikan untuk mempertahankannya ... sungguh kacau!


Dan sekarang ide gila yang datang padaku sekarang

Klon copy-on-write

m = moment();
funcIDontTrust(m.clone());  // doesn't actually clone

function funcIDontTrust(m) {
  m.year(2005);  // perform the clone here
  console.log(m);
}

Saya tidak yakin berapa banyak yang bisa dikurangi dengan pendekatan ini, mengingat contoh momen cukup ringan. Juga semua mutator sekarang harus melakukan pemeriksaan.

Ada beberapa cara untuk menerapkan dengan kinerja yang berbeda-beda dalam skenario yang berbeda. Kabar baiknya adalah bahwa ini kompatibel ke belakang dan kami akan menghemat banyak usaha bagi kami dan pengguna kami. Dan saya pikir ini lebih penting daripada menciptakan kembali roda.

Saya tidak yakin apa yang kita dapatkan di sini.

Beralih ke immuttablilty memiliki banyak biaya terkait dan mungkin saya melewatkannya, tapi
Saya tidak benar-benar melihat manfaat yang sebanding.

Manfaat utama tampaknya menjadi preferensi pengembang. Apakah ini semua agar pengembang tidak memiliki
untuk berpikir tentang kepemilikan momen ketika melewatinya?

Saya tidak berpikir beralih ke kekekalan akan membuat bug lebih jarang, itu hanya akan
mengubah jenis bug. Contoh @ichernev bahkan menunjukkan jenis bug yang tepat yang akan
permukaan, yang sama sulitnya untuk dilacak.

m = moment();
funcIDontTrust(m.clone());  // doesn't actually clone

function funcIDontTrust(m) {
  m.year(2005);  // perform the clone here
  // m is still in 2014
  // m.year(2005) created a clone but did not assign it to anything
  // it should be `m = m.year(2005)`
  console.log(m);
}

Berikut adalah daftar pro/kontra antara mutabilitas dan immutabilitas. Jika saya melewatkan sesuatu,
beri tahu saya dan saya akan mengedit komentar ini.

| Tidak berubah | Bisa Diubah |
| --- | --- |
| Beberapa pengembang lebih menyukainya | Beberapa pengembang lain lebih menyukainya |
| Menghindari bug saat melewati momen | Menghindari bug saat lupa menetapkan momen kloning |
| Dengan beberapa lusin metode api baru, mutabilitas juga akan didukung | Dengan metode .clone() yang ada, kekekalan sudah didukung |
| | Urutan besarnya lebih cepat |
| | Menggunakan memori yang jauh lebih sedikit |

Saya pikir kekekalan berguna, tetapi saya tidak berpikir itu cocok dengan JavaScript. Saya pikir antarmuka yang tidak dapat diubah mungkin masuk akal untuk bahasa seperti Elm, di mana kekekalan diharapkan, tetapi untuk JavaScript, saya pikir perubahan diharapkan.

Sebagian besar api untuk typeof a === "object" built-in bisa berubah. Array#push,pop,reverse,sort,shift,splice,unshift semua mengubah isi array daripada mengembalikan array baru. Semua 16 metode Date#setX memutasikan instance mereka.

Saya pikir kita melihat banyak orang mengeluh tentang momen yang bisa berubah, tetapi jika kita beralih, saya pikir kita akan memiliki banyak orang yang mengeluh. Ini telah terjadi dengan metode eod/sod dua tahun lalu.

Setelah melihat banyak masalah lama tentang mutabilitas, saya kira saya mungkin terdengar seperti kaset rusak di sini. Di kedua sisi, itu adalah poin yang sama yang telah diangkat selama beberapa tahun terakhir. Saya hanya ingin memastikan argumen untuk menjaga api yang bisa berubah diwakili dalam diskusi.

@timrwood itu perbandingan yang bagus, tetapi cukup jelas Anda belum meluangkan waktu untuk memahami kasus penggunaan yang tidak dapat diubah. Kami telah membahas mengapa perbandingan kinerja yang Anda posting mengasumsikan API yang diterapkan dengan buruk dan tidak masuk akal.

Perbandingan bug juga tidak valid. Karena momentjs mendukung chaining API, orang dapat mengharapkannya untuk tidak berubah.

var newM = m.year(2005) // wrong, these are both the same!

Jadi baik yang tidak berubah maupun yang bisa berubah memiliki masalah yang sama saat ini. Anda dapat menghindarinya dengan versi yang dapat diubah saat ini jika Anda menyingkirkan API rantai.

Jadi API yang tidak dapat diubah lebih disukai daripada yang dapat diubah karena Anda dapat dengan aman melewatkan momen di antara fungsi. Dengan momen yang bisa berubah saat ini jika saya melewatkan momen di antara fungsi, saya memiliki 2 opsi

1) Cara kereta gila (yang mungkin paling umum): selidiki semua kode sumber untuk memastikan tidak ada mutasi yang tidak diinginkan. Tulis tes unit untuk memastikan mutasi yang tidak diinginkan tidak masuk.
2) Cara yang waras (mari kita asumsikan semua orang melakukan ini), pemrograman defensif: ingatlah untuk memanggil fungsi clone() sebelum bermutasi di fungsi saya.

Dengan API yang tidak dapat diubah, kita tidak perlu mengingat untuk memanggil clone() setiap saat. Sebagai gantinya, kita harus ingat untuk memanggil fungsi API yang memungkinkan kita menghindari kloning, tetapi ini hanya pengoptimalan kinerja, bukan masalah kebenaran.

cukup jelas Anda belum meluangkan waktu untuk memahami kasus penggunaan yang tidak dapat diubah

Itu pernyataan yang tidak adil. Argumen saya adalah bahwa saya melihat manfaatnya, tetapi tidak berpikir bahwa itu lebih besar daripada biayanya.

Anda dapat dengan aman melewatkan momen di antara fungsi

kita tidak harus ingat untuk memanggil clone

Apakah ini bukan kasus penggunaan untuk kekekalan? Jika ada lebih dari itu yang saya belum meluangkan waktu untuk memahaminya, tolong beri tahu saya, tetapi ini tampaknya menjadi satu-satunya argumen selama beberapa tahun terakhir.

@timrwood ya, itulah keseluruhan kasusnya.

Tapi saya tidak melihat tanda dari Anda yang mengakui bahwa kasus Anda _against_ immutability (kinerja mengerikan, mempromosikan jenis bug berbeda yang tidak ada di API yang bisa berubah) tidak valid.

saya pikir kita harus tetap menggunakan sudut pandang ecmascript 5, dan mungkin menambahkan fungsi yang membekukan objek saat ini, atau bendera global yang secara otomatis membuat objek frezee

http://blogorama.nerdworks.in/preventextensionssealandfreeze/

mungkin parameter tambahan di konstruktor untuk membuat objek beku, karena objek beku tidak dapat dicairkan

@lfnavess Saya memikirkan freeze sebelum menyebutkan salinannya saat menulis. Masalahnya adalah ... tidak ada yang menggunakannya / mengetahuinya, juga tidak membantu ketika tidak mengeluarkan pengecualian (dalam mode non-ketat) -- itu benar-benar menciptakan bug gila untuk Anda lacak.

@timrwood Saya rasa saya tidak menjelaskan contoh saya. Di baris m.year(2014) // clone here Maksud saya momen internal sebenarnya akan membuat klon (mengalokasikan lebih banyak memori) dan m akan menunjuk ke memori baru itu, secara otomatis. Yah itu pada dasarnya berarti bahwa clone() juga harus mengalokasikan sedikit memori shell (sesuatu untuk menunjuk ke representasi tanggal internal), saya hanya tidak yakin berapa banyak yang akan diperoleh dengan melakukannya.

Membuat versi setengah-setengah dari clone , yang hanya mengkloning antarmuka, dan kemampuan untuk mengubah data yang mendasarinya (dari penyimpanan bersama ke spesifik-instance) -- itu benar-benar tergantung pada seberapa mahal objek Date. Kelemahannya adalah bahwa setiap fungsi perlu dilakukan this._storage._d alih-alih this._d , dan saya tidak yakin apakah itu akan mengatasi manfaatnya.

Saya tidak mendapatkan komentar apa pun tentang cara menangani migrasi perpustakaan/pengguna yang ada saat ini. Saya tidak terlalu menyukai salah satu opsi yang saya sebutkan di atas.

Kompatibilitas terbalik adalah, IMO, argumen terkuat menentang ini. Jika kita melakukan ini, kita hanya harus menerima bahwa ini adalah perubahan besar. Jika kita tidak mau menerimanya, sebaiknya kita tidak melakukannya.

Perlu disebutkan re:perf bahwa ada juga beberapa keuntungan besar yang bisa Anda peroleh dari kekekalan; itu bukan hit perf monoton. Misalnya, Anda dapat menyimpan sesuatu di tingkat objek, karena tidak akan pernah berubah. Saya juga berpikir kita harus dapat mengoptimalkan omong kosong hidup dari clone() ; AFAIK melibatkan kloning tanggal dan menyalin seperti lima nilai; Saya pikir kita harus membuat hardcode mereka seperti newThing._offset = oldThing._offset .

Edit, arg, no - plugins tambahkan juga bidang (mis. di sini ).

mengingat keinginan yang kuat untuk kompatibilitas ke belakang dan tetap menjaganya tetap ringan, saya pikir solusi terbaik adalah dengan memotong sumber javascript (baik dalam sumber proyek ini atau memulai proyek yang sama sekali baru). Ada ruang untuk lebih dari 1 kali perpustakaan untuk internet.

Juga: ide re: @ichernev tentang berbagi struktural, satu kemungkinan adalah menggunakan pewarisan prototipe alih-alih membungkus objek status bersama.

Kami di WhoopInc telah mengintai dalam diskusi ini cukup lama. Karena diskusi di sini tampaknya berputar-putar, saya meluangkan waktu akhir pekan ini untuk menjelajahi seperti apa versi momen yang tidak dapat diubah dengan API pembangun. (Saya tidak berniat mengirimkan PR terhadap momen kecuali diundang untuk melakukannya, karena saya sengaja membuat perubahan API yang lebih keras daripada yang saya harapkan untuk diterapkan pada saat itu sendiri.) Inilah hasilnya: https://github. com/WhoopInc/momen beku

Saya baru beberapa jam, jadi semuanya benar-benar kasar, tetapi berdasarkan hasil pengujian, saya pikir sebagian besar fungsionalitas momen inti berfungsi. Saya akan terus melacak percakapan ini, dan saya akan menyambut umpan balik khusus untuk garpu kami dalam masalah repo kami.

Saya akan mencoba menerbitkan beberapa dokumen yang diperbarui pada repo itu malam ini, tetapi pada dasarnya saya hanya membagi semua metode penyetel dan mutasi menjadi objek pembangun yang terpisah. Jadi menggunakan API mungkin terlihat seperti frozenMoment("2014-07-21").thaw().subtract(1, "day").startOf("day").freeze().format("YYYY-MM-DD") . (Meskipun dalam contoh khusus ini akan lebih efisien untuk memulai rantai dengan builder daripada menginisialisasi builder dari frozenMoment, menggunakan frozenMoment.build("2014-07-21").subtract... )

FWIW, ketika saya mulai menggunakan momen saya berasumsi itu mengikuti prinsip FP dan akan mengembalikan nilai yang sama setiap kali saya memanggil suatu fungsi:

var now = moment();
var yesterday = now.subtract(1, 'days');
var dayBeforeYesterday = now.subtract(2, 'days');

Tentu saja, saya tidak mendapatkan hasil yang saya harapkan. Ini membuat saya lengah sebagai pengguna baru.

Pertimbangkan kodesemu ini, yang menunjukkan bagaimana saya mengharapkan kode berperilaku:

var now = now;
var yesterday = now - 1day;
var dayBeforeYesterday = now - 2days;

Tetapi malah akhirnya bekerja seperti ini, yang terasa aneh bagi saya:

var now = now;
var yesterday = now = now - 1day;
var dayBeforeYesterday = now = now - 2days;

Untuk saat ini, meskipun cukup membosankan, saya hanya berhati-hati .clone() mana-mana.

var now = moment();
var yesterday = now.clone().subtract(1, 'days');
var dayBeforeYesterday = now.clone().subtract(2, 'days');

IMO, Javascript rentan terhadap kesalahan halus dan saya merasa bahwa prinsip FP membantu meminimalkan kesalahan itu.

Saya bersimpati bahwa ini adalah keputusan yang sulit untuk dibuat. Saya menghargai pekerjaan Anda. Moment.js luar biasa.

+1 untuk 100% kekekalan.

Sejujurnya agak membuat frustrasi karena tidak dapat diubah.

+1 untuk kekekalan 100% dalam versi 3

Pasti harus ada API yang tidak dapat diubah. Sebagai pengguna perpustakaan tanggal lain (terutama, .NET DateTime dan Waktu Joda / Waktu Noda), saya secara intuitif berharap bahwa metode add tidak akan mengubah objek tanggal.

+1 untuk kekekalan

+1 untuk 100% kekekalan

Jika keputusan dibuat untuk kekekalan, saya akan bersedia memberikan waktu saya untuk mewujudkannya. Mungkin memasangkan melalui panggilan video. Saya ingin berkontribusi lebih banyak untuk open source tetapi perlu mempelajari seluk beluknya.

Bagi saya, kekekalan lebih disukai, tetapi itu seharusnya dilakukan sejak awal. Ini adalah perubahan yang sangat drastis. Sebuah garpu dari proyek ini yang berfokus pada kekekalan akan menjadi ide yang lebih baik.

@dsherret Untuk itulah semver . Kami baru saja menabrak versi utama.

Namun, dengan beberapa upaya itu dapat diperkenalkan sebagai opsi konfigurasi: "Apakah Anda ingin semuanya tidak berubah? Benar atau Salah". Default akan salah.

Plugin momen abadi ymmv tidak resmi yang tidak didukung di sini: https://Gist.github.com/timrwood/fcd0925bb779f4374a7c

Ha ha! Saya terkejut datang ke sini jauh kemudian dan menemukan bahwa saya adalah salah satu pendukung pertama untuk API yang lebih abadi.. :)

Dan ya saya memberi +1 untuk kekekalan untuk versi utama berikutnya.

+1 lain untuk momen yang tidak dapat diubah-by-default dari saya.
Dan inilah ramuan 'imoment' saya: https://Gist.github.com/idrm/a91dc7a4cfb381dca24e (gunakan dengan risiko Anda sendiri!). Ganti saja panggilan moment() Anda dengan imoment() dan itu sudah cukup. Semua panggilan fungsi moment.xyz() (misalnya moment.min(), moment.max(), dll.) harus tetap apa adanya.

+1 juta dolar

+1 untuk kekekalan

Bolehkah saya juga menambahkan +1 ke saran sebelumnya dari utas diskusi ini untuk mengganti nama beberapa fungsi sehingga lebih mudah dibaca ("startOf" menjadi "toStartOf", "add" to "plus", "month" menjadi "withMonth ", dll.)? Artinya, dengan asumsi Anda mengambil rute yang tidak dapat diubah-by-default. Saya sering menggunakan Joda Time, dan sangat mudah untuk mengetahui apa, misalnya, "date.withDayOfMonth(1).withDayOfWeek(DateTimeConstants.MONDAY)" artinya.
Ini juga tidak harus di JS distro utama; sebuah add-on yang menampar ini di atas vanilla JS akan bekerja dengan baik (heck, saya sangat mempertimbangkan untuk menulis sendiri add-on yang disejajarkan dengan Joda Time untuk digabungkan dengan mod "imoment" saya).

@ichernev , @icambron , apakah Anda sudah membuat keputusan tentang ini? Akankah momen tidak akan berubah di 3.0? Jika demikian: kapan Anda berharap 3.0 akan keluar? Saya bertanya karena saya sedang mempertimbangkan untuk menggunakan momen beku atau menulis bungkus kecil sendiri – dan saya bertanya-tanya apakah saya harus menunggu.

FYI, momen beku sebagian besar berada dalam pola penahanan baru-baru ini -- Saya telah mem-porting banyak PR dari Momen hulu, tetapi belum benar-benar mengerjakan salah satu refactoring lain yang idealnya terjadi di fork itu.

Yang mengatakan, momen beku akan berfungsi dengan baik jika Anda hanya membutuhkan lokal bahasa Inggris default. (Semuanya berfungsi untuk kasus penggunaan saya, dan saya telah mempertahankan cakupan pengujian unit Momen yang tinggi.) Lokal non-Inggris rusak karena saya tidak memperbaruinya setelah mem-porting API lokal Momen yang baru-baru ini direfaktor.

Setelah kita memiliki keputusan untuk Momen 3.0, saya akan berencana untuk bekerja sedikit lebih serius pada pekerjaan kekekalan di Momen, atau pada garpu momen beku, sebagaimana mestinya. Tujuan awal saya adalah memperbaiki dukungan lokal dan mempertahankan paritas fitur dengan API Moment 3.0.

+1 untuk kekekalan

+1 untuk kekekalan. Bagaimana dengan metode format yang juga mengubah objek?

+1 untuk momen abadi.js
Atau mungkin garpu moment.js? tidak berubah-moment.js? Karena ini pasti akan menjadi perubahan besar.

:100:
lakukan imootable!

+1 hari ini kekekalan adalah sesuatu yang saya harapkan di JS API yang bagus

:+1: Ya tolong, kami akan sangat menyukai ini. Saat ini kami menaburkan .clone() di mana-mana.

+1 ini akan menjadi peningkatan yang sangat bagus

:+1: semua hal tidak dapat diubah

+1 untuk tidak berubah

Jadikan semuanya tidak berubah. Saya muak dengan mengkloning variabel setiap momen (sekarang) sebelum saya mengoperasikan variabel sekarang dan kemudian sekarang diubah lagi.

+1 untuk kekekalan

Saya tidak akan mengharapkan startOf('day') untuk bermutasi (walaupun saya akan mengakuinya didokumentasikan dengan baik jika saya telah membaca lebih hati-hati). Itu menyebabkan bug yang menyenangkan di aplikasi saya.

Saya sangat setuju bahwa sebagian besar operator moment.js canggung dalam perubahannya. mmnt.startOf('day') adalah penghitung super intuitif yang bermutasi mmnt .

Saya menggunakan moment.js untuk kasus penggunaan tipe kalender dengan banyak pengulangan dan perbandingan tanggal. Saya telah mengalami masalah kinerja dengan clone() dan itu mengerikan. Memiliki beberapa kontrol atas apa klon dan apa bermutasi sangat penting bagi saya dan mungkin orang lain.
Meskipun memiliki clone() mana-mana tampak canggung pada awalnya, apa yang dilakukannya sangat jelas dan membuat refactoring untuk kinerja menjadi sangat mudah bagi saya.

Jika setiap metode mulai membabi buta menggunakan clone() internal demi memiliki API yang lebih bagus, saya pikir kita akan melewatkan intinya.

2 saya :-)

@jdurand Saya lebih suka bermutasi secara eksplisit daripada mengkloning secara eksplisit.

@dsherret Saya tidak keberatan secara eksplisit apa pun. Perhatian utama saya adalah tentang tidak mengkloning secara implisit karena ini adalah operasi yang sangat mahal.
Seseorang menyebutkan bahwa setter perlu mengembalikan salinan kloning dan itu membuatku takut; Itu akan sangat tidak efisien.

@jdurand mungkin lebih tidak efisien, tetapi saya pikir klon implisit akan menguntungkan sebagian besar aplikasi di mana perbedaan antara objek yang dikloning dan bermutasi tidak akan membuat perbedaan nyata pada pengalaman pengguna akhir. Saya pikir kemudahan pengembang dan mencoba mencegah kesalahan pengembang harus didahulukan daripada beberapa milidetik yang disimpan, karena mayoritas pengembang tidak melakukan ribuan operasi tanggal sekaligus. Bagi mereka yang melakukannya, mereka mungkin secara eksplisit mengatakan bahwa mereka ingin bermutasi daripada mengkloning.

Sidenote: dengan perubahan ini saya pikir beberapa peningkatan kinerja dapat dilakukan ... misalnya, kloning dapat dihilangkan dengan merujuk ke objek yang tidak dapat diubah sebelumnya dan kemudian menyimpan operasi yang harus dilakukan untuk objek ini (mis. add(1, 'days') ). Hasilnya hanya akan dihitung dengan menjalankan operasi ketika sesuatu seperti .toString() , .format() , .toDate() , .day() , dll... dipanggil. Itu akan menjadi perubahan dramatis dan mungkin tidak akan berakhir lebih cepat ... beberapa tes unit perlu dilakukan untuk membandingkan kinerja (selain itu mungkin ada masalah lain yang belum saya pertimbangkan karena saya belum pernah melihat kode apa pun di moment.js selain cara mengkloningnya).

@dsherret Saya suka pendekatan _builder_/_lazy_; dengan melihat ke belakang, mungkin seharusnya dibangun seperti ini dari awal.
Seperti yang Anda katakan, saya pikir garpu yang tidak dapat diubah dengan kompatibilitas API dalam pikiran akan menjadi yang terbaik.

2 sen lagi:

  1. Haruskah kita benar-benar khawatir tentang kinerja, ketika momen jelas dibangun untuk kenyamanan daripada kinerja? Saya akan berpikir bahwa penguraian 'tahun' di m.add('tahun',1) jauh lebih lambat daripada kloning.
  2. Kecuali ada garpu total (nama berbeda, doc berbeda), akan merepotkan untuk mempertahankan 2 versi. Saya pikir seseorang yang pintar harus datang dengan ide untuk menghasilkan moment.immutable.min.js dan moment.min.js dari basis kode yang sama...

Sejak kapan kita begitu takut melanggar perubahan? Versi saat ini stabil dan orang masih dapat menggunakannya tanpa memfaktorkan ulang basis kode mereka.

Mempertahankan dua basis kode itu menyebalkan, memperlambat Anda dan tidak terlalu berharga hanya untuk memiliki versi yang bisa berubah/tidak dapat diubah.

Jadi mari kita pergi dengan momen yang sepenuhnya tidak dapat diubah, menabrak versi utama dan selesai dengan itu :dancers:

Menemukan utas ini ketika saya baru saja mulai menggunakan perpustakaan ini tetapi telah mencabut rambut saya untuk men-debug beberapa kode dan berurusan dengan apa yang bagi saya tampaknya merupakan efek samping yang tidak dapat diprediksi karena bisa berubah. Akan senang melihat versi perpustakaan yang sepenuhnya tidak dapat diubah!

Steker tak tahu malu: Saya bosan menunggu keputusan tegas di sini. Selama beberapa hari terakhir, saya telah menghidupkan kembali Momen Beku dan menulis ulang untuk bertindak sebagai plugin untuk Momen itu sendiri. Kiat topi untuk @wyantb karena membantu saya menyelesaikan rilis pratinjau pertama selama akhir pekan.

Frozen Moment menyediakan tipe yang tidak dapat diubah yang berfungsi seperti Moment. Pada dasarnya, versi immutable membungkus fungsionalitas Moment dan memanggil .clone() untuk Anda kapan pun diperlukan.

Bagi mereka yang menyukai API pembangun, saya menantang Anda untuk memikirkan Momen itu sendiri sebagai implementasi yang sangat bagus dari objek pembangun! Momen Beku menambahkan tipe inti yang tidak dapat diubah yang kita semua inginkan, dan mekanisme untuk membangun Momen Beku yang tidak dapat diubah dari Momen yang dapat diubah.

Bagi mereka yang hanya ingin bekerja dengan API yang nyaman dan tidak dapat diubah -- saya juga ingin mendukungnya. Saya belum membangun konstruktor yang akan langsung membuat instance Frozen, tapi itu ada di daftar TODO . Dalam jangka pendek, solusinya adalah membuat semuanya dengan moment().freeze() atau moment.utc().freeze() .

Frozen Moment jelas merupakan basis kode muda, jadi mungkin ada beberapa sisi kasar -- tapi saya mendorong siapa pun di sini untuk mencobanya dan mengajukan masalah untuk apa pun yang tidak berfungsi seperti yang Anda harapkan.

Oh, satu hal lagi: Saya belum mengiklankan ini, tetapi instans Momen Beku seharusnya "berfungsi" dengan sebagian besar plugin Momen. Pastikan saja semua plugin Momen Anda yang lain mendaftar sendiri sebelum Momen Beku. Jika Anda menemukan plugin yang tidak berfungsi seperti yang diharapkan dengan Momen Beku yang tidak dapat diubah, laporkan bug dan saya akan memeriksanya.

+1 pada kekekalan

+1 untuk tidak berubah

Apakah ada yang melihat momen implementasi di atas JS yang tidak dapat diubah ? Ini adalah perpustakaan yang dioptimalkan untuk kekekalan di JS, menggunakan kembali bagian yang tidak berubah dari objek yang tidak dapat diubah, mengurangi masalah memori.

+1
Saya baru saja memperbaiki bug berusia 3 tahun karena ini: https://github.com/Saleslogix/argos-saleslogix/commit/87b35b22c1a42670da369701b15e2bdb3786cabc

Jadi pengguna meminta kekekalan tetapi tim inti menemukan alasan untuk tidak melakukannya? :P
Ayo teman-teman, perubahan ini jauh lebih penting daripada menulis ulang kode di ES6 ^^ Dalam bentuknya saat ini, API-nya buruk, sedikit seperti JS Array di mana beberapa metode tidak dapat diubah (filter, concat, dll) tetapi beberapa yang lain tidak (mundur, urutkan) kecuali batasannya untuk kompatibilitas mundur jauh lebih tinggi daripada perpustakaan.

+1

jebakan kecil yang selalu membuat saya (dan IMHO ini adalah alasan bagus untuk kekekalan):

var today = moment();
for (var i = 0; i < 7; i++) {
   week.push(today.subtract(i, 'days').format('dd').toUpperCase());
}

sayangnya ini tidak menghasilkan array dengan nama hari tetapi sesuatu yang aneh karena Anda sebenarnya menghitung tanggal seperti ini:

i = 0 = today -0;
i = 1 = today -0 -1;
i = 2 = today -0 -1 -2;
etc

jadi Anda harus refactor menjadi ini:

var today = moment();
for (var i = 0; i < 7; i++) {
            if (i == 0) {
                week.push(today.subtract(0, 'days').format('dd').toUpperCase());
            }
            else {
                week.push(today.subtract(1, 'days').format('dd').toUpperCase());
            }
        }

@faebser contoh luar biasa

+1 untuk kekekalan

+1

@faebser terjadi pada saya pagi ini. Pengikatan dua arah + mutabilitas Angular menyulitkan ** untuk menjaga tanggal kloning agar tidak memodifikasi yang sekarang.

+1 untuk kekekalan, ini hanya menghabiskan beberapa jam.

:+1:

+1 untuk kekekalan

Saya agak bingung tentang topik ini.

Yang murni dalam diri saya ingin berteriak "+1 untuk kekekalan! Objek momen jelas dari jenis ValueObject ."

Namun, kita tidak dapat mengabaikan bahwa moment.js adalah repo javascript terpopuler ke - ke - 111 hasil yang cocok. Bahkan jika kami dapat menyediakan pembuat aplikasi dengan cara bertahap untuk mengimplementasikan versi momen yang tidak dapat diubah, itu akan menyebabkan kekacauan besar di antara dependensinya.

@ichernev Mungkin saran yang lebih sederhana: Apakah mungkin mencurahkan sebagian kecil halaman dokumentasi momen untuk berbicara tentang mutabilitas vs kekekalan? Anda dapat secara singkat menyatakan sikap resmi Anda tentang topik tersebut, dan mungkin menambahkan ringkasan argumen singkat, menempatkan tautan ke utas ini, atau jika Anda menginginkan masukan diskusi khusus, ini dapat berfungsi seperti CTA.

Saat ini halaman dokumentasi tidak menyebutkan istilah "tidak dapat diubah". Googling "momen abadi" membawa Anda ke halaman ini, tetapi saya butuh dua jam membaca dan saya masih tidak yakin tentang sikap Anda saat ini tentang topik tersebut. Akan sangat bagus jika hit teratas Google untuk "moment immutable" memberikan jawaban cepat tentang masa depan immutability in moment :)

Mengutip @jehoshua02 :
"Saya bersimpati bahwa ini adalah keputusan yang sulit untuk dibuat. Saya menghargai pekerjaan Anda. Moment.js luar biasa."

Berikut proposal saya. Alih-alih membuat momen dasar tidak berubah, tambahkan pabrik moment.immutable . Itu akan menjadi properti dari fungsi moment dan akan menyertakan tanda tangan API yang sama persis dengan moment , tetapi tidak dapat diubah.

Itu bahkan bisa menjadi perpanjangan prototipe dari pabrik moment dapat diubah, menggunakan fungsi prototipe itu, tetapi mengkloning sebagai gantinya.

EDIT: Tampaknya WhoopInc/frozen-moment persis seperti yang saya cari.

@thomasvanlankveld melanggar perubahan adalah untuk apa nomor versi utama. Siapa pun yang menggunakan Bower dan npm akan memiliki opsi untuk tetap menggunakan nomor versi utama saat ini; kita tidak perlu khawatir tentang kompatibilitas mundur di sini - kecuali mungkin orang-orang yang hanya menyajikan ini dari CDN. Tetapi jika mereka menggunakan momentjs dari CDN, mereka mungkin tidak terlalu tertarik untuk memperbarui perpustakaan dari waktu ke waktu.

Saya berpendapat bahwa memiliki kekekalan dalam versi utama berikutnya - atau versi utama setelah itu - harus ada di peta jalan.

Jadi sepertinya saya baru saja mengalami masalah ini juga.

http://stackoverflow.com/questions/33002430/moment-js-formatting-incorrect-date

Jadi saya semua untuk kekekalan di seluruh papan.

+1 Untuk kekekalan

Baru saja kehilangan malam karena perilaku mengejutkan dan tak terduga ini.
+1 lain untuk kekekalan dengan perubahan versi utama yang sesuai untuk memperjelasnya.

+1 Untuk kekekalan

+1 untuk kekekalan penuh.
Jumlah kolektif jam yang hilang karena "terkadang bisa berubah, terkadang tidak berubah" pasti cukup besar.

Ya maksud saya serius. Siapa yang peduli dengan kinerja di perpustakaan datetime? Seperti.. benarkah? Saya menduga 99,9% pengguna tidak melakukan apa pun yang bahkan membutuhkan kinerja yang baik dari jarak jauh. Biasanya Anda menangani beberapa kencan, atau dalam kasus terburuk beberapa ratus. Beberapa pengguna yang menangani jutaan tanggal per detik dapat menggunakan titik API yang dapat diubah yang dioptimalkan.

Kekekalan adalah satu-satunya pilihan desain yang waras. Ada beberapa penelitian yang menunjukkan bahwa pemrograman dengan tipe yang tidak dapat diubah jauh lebih rentan terhadap bug dibandingkan dengan tipe yang dapat diubah.

+1 untuk kekekalan. Ini menghabiskan beberapa jam.

Sebagian masalahnya adalah bahwa nama metode seperti .startOf() tidak menyiratkan mutasi dari objek yang mendasarinya.

Saya telah mencapai kemacetan kinerja dengan Momen, jadi saya dapat meyakinkan Anda bahwa ini kadang-kadang bisa terjadi.

Namun, saya tidak yakin bahwa momen yang tidak dapat diubah secara inheren kurang efisien, dan dapat membayangkan beberapa kasus di mana mereka akan lebih efisien.

Perdebatan ini sudah lama diselesaikan di dunia Jawa. Tanggal abadi menang, dan implementasi paling populer (JodaTime) akhirnya menjadi bagian dari perpustakaan standar di Java 8.

Bekerja dengan LocalTime Java 8 telah menjadi salah satu hal yang mengejutkan "Mengapa kita tidak _selalu_ melakukan ini?" momen. Saya jarang menginjili teknologi, tetapi sejujurnya saya tidak dapat melihat keuntungan apa pun dari objek tanggal yang bisa berubah.

Jadi, ya.... Saya benci bahwa utas ini dibanjiri +1, tetapi kenyataannya adalah bahwa orang lain akan membuat perpustakaan tanggal JS yang tidak dapat diubah jika Moment tidak.

Saya baru-baru ini menemukan modul npm baru yang dimaksudkan untuk mem-port sebagian besar JodaTime API (yaitu tanggal Java 8) ke JS.

Ini akan membawa hal-hal seperti kekekalan, LocalDate, dan LocalTime ke node dan browser.

Setelah bekerja dengan konsep-konsep ini di Jawa, segala sesuatu yang lain terasa kludge-y dan rawan bug.

Tautan?

Pada Jum, 11 Des 2015, 16:30 Andrew Schmadel [email protected]
menulis:

Saya baru-baru ini menemukan modul npm baru yang dimaksudkan untuk banyak port
JodaTime API (yaitu tanggal Java 8) ke JS.

Ini akan membawa hal-hal seperti kekekalan, LocalDate, dan LocalTime ke
simpul dan browser.

Setelah bekerja dengan konsep-konsep ini di Jawa, semuanya terasa kludge-y
dan rawan bug.


Balas email ini secara langsung atau lihat di GitHub
https://github.com/moment/moment/issues/1754#issuecomment -163964349.

Tidak.
(diketik di ponsel, maaf singkat)

Karena saya belum menimpali, saya hanya akan menyatakan bahwa saya mendukung kekekalan di momen 3.0. Terutama karena saya berasal dari aliran pemikiran DDD, di mana objek seperti moment akan dianggap _nilai objek_, dan dengan demikian paling baik diterapkan sebagai tidak dapat diubah.

Bahkan jika ada peningkatan kinerja yang signifikan, itu masih merupakan hal yang benar untuk dilakukan. Momen harus cocok secara alami dengan desain orang lain. API intuitif mengalahkan kinerja, dan mutasi tidak intuitif pada objek nilai (IMHO).

Saya juga berpikir momen 3.0 harus menghapus ketergantungannya pada objek Date , tapi itu diskusi untuk utas yang berbeda.

Saya sepenuhnya setuju dengan @ mj1856 di sini.

Saya telah menggunakan Object.freeze pada saat-saat tertentu dan ini secara umum telah mencapai apa yang saya butuhkan; kecuali saya baru saja menemukan bahwa yang berikut ini gagal:

let now = Object.freeze(moment());
if (now.isSameOrBefore(anotherTime)) { // throws exception
}

Pengecualian:

TypeError: Can't add property _isValid, object is not extensible
 at valid__isValid (C:\git\quick-test\node_modules\moment\moment.js:93:24)
 at Moment.moment_valid__isValid [as isValid] (C:\git\quick-test\node_modules\moment\moment.js:2195:16)
 at Moment.isSame (C:\git\quick-test\node_modules\moment\moment.js:1945:44)
 at Moment.isSameOrBefore (C:\git\quick-test\node_modules\moment\moment.js:1962:21)

Bisakah ini diperbaiki sehingga Object.freeze dapat digunakan saat diinginkan?

@wmertens Saya berasumsi ini dia: https://github.com/pithu/js-joda

@ichernev , @mj1856 , karena saya sudah lama tidak terlibat dalam pengembangan inti momen dan kekekalan memiliki minat yang cukup signifikan, saya menarik kembali pendirian saya sebelumnya.

Saya tidak yakin apakah saya satu-satunya pemblokir dalam hal ini, tetapi saya merasa nyaman bergerak maju dengan kekekalan di 3.0.

@gabrielmaldi @wmertens Yap. Itu saja. Maaf atas komentar saya yang tidak jelas batasnya -- saya dengan jelas mengeklik tombol 'Kirim' pada postingan yang setengah jadi.

Untuk mengumpulkan beberapa pemikiran saya yang terputus-putus:

  • Jelas ada minat pada objek tanggal yang tidak dapat diubah untuk JS. Ada perpustakaan tanggal dewasa yang tidak dapat diubah dalam beberapa bahasa lain, dan ada banyak momentum umum terhadap objek yang tidak dapat diubah di JS ( immutable.js memiliki 10.500 bintang jika itu indikasi). Paling tidak, saya pikir ini layak mendapatkan bukti konsep.
  • Terlepas dari minat ini, sangat sedikit kode yang tampaknya telah ditulis. js-joda tampaknya merupakan upaya serius pertama untuk menulis perpustakaan tanggal yang tidak dapat diubah untuk JS.
  • Saat-saat yang tidak dapat diubah akan menjadi perubahan besar yang menghancurkan, yang menimbulkan beberapa pertanyaan filosofis. Meskipun saya benci kehilangan dukungan dari komunitas MomentJS yang sangat besar, itu tidak selalu menjadi hal yang mengerikan bagi kita yang tertarik pada tanggal JS yang tidak dapat diubah untuk membuat terobosan yang bersih, dan berkontribusi pada js-joda alih-alih mencoba untuk mendorong perubahan yang cukup radikal pada Moment (perpustakaan yang matang dengan basis pengguna yang besar dan mapan).
  • Selain: js-joda masih sangat muda, dan tidak jelas apa tujuan dan niat penulis untuk perpustakaan. Secara khusus, dia perlu memilih lisensi, dan kami mungkin ingin mempertimbangkan apakah kebutuhan pengembang JS biasa akan dipenuhi oleh implementasi ulang Joda Time atau JSR-310 yang setia.

+1 untuk kekekalan, dan kode yang lebih waras yang akan dihasilkan.

Ini akan menjadi upaya besar, jadi terima kasih yang tulus kepada mereka yang akan (dan telah) mewujudkannya.

Momen cukup banyak digunakan sehingga saya pikir itu dapat ditindaklanjuti dengan sesuatu yang mendekati yang berikut, dengan asumsi diimplementasikan mirip dengan @butterflyhug https://github.com/WhoopInc/frozen-moment

3.x: tidak dapat diubah sebagai opsi, default ke false, dan memiliki flag yang disetel pada ekspor momen global yang akan disetel ke true; console.warn pada beban perpustakaan (dalam mode dev)
4.x: tidak dapat diubah sebagai opsi, default ke true, flag masih tersedia untuk disetel sebagai false; console.warn tentang jadwal untuk 5.x (dalam mode dev)
5.x: tidak berubah sebagai satu-satunya cara

Miliki halaman di bagian depan dan tengah yang menggambarkan visi kekekalan jangka panjang - katakanlah, satu rilis besar setahun di sepanjang garis besar 3.x/4.x/5.x yang saya buat - dan saya pikir itu akan memberikan alasan yang masuk akal jumlah bagi siapa pun yang terpengaruh untuk memperbarui kode mereka.

Beberapa pengamatan:

  1. Saya membangun WhoopInc/frozen-moment dengan harapan banyak orang di sini mungkin bersedia membangun sesuatu dengannya, sebagai cara untuk menemukan titik masalah di ekosistem saat kekekalan akan merusak plugin, dll. Sejauh ini, hanya sedikit orang yang melakukannya , yang membuat saya kurang bersemangat untuk mengerjakan momen beku dan/atau penginjilan komunitas untuk membantu penulis plugin mendukung momen abadi.

Yang mengatakan, saya masih bersedia membantu memperbaiki bug yang ditemukan orang saat menggunakan momen beku -- terlepas dari apakah bug itu milik saya atau apakah mereka berada di plugin momen lain yang tidak pernah mempertimbangkan kemungkinan momen menjadi tidak dapat diubah. Ajukan saja masalah saat beku dan saya akan memeriksanya. Dan saya masih berpikir bahwa upaya komunitas di sekitar sesuatu seperti momen beku dapat membantu kita memahami dan meringankan penderitaan transisi ke momen abadi.

  1. Jika momen mengimplementasikan kekekalan di 3.0, akan sangat mudah bagi seseorang untuk menulis dan memelihara pembungkus untuk mengimplementasikan momen 2.x API yang dapat diubah di atas API 3.x yang tidak dapat diubah. Secara konseptual, ini sebenarnya akan sangat mirip dengan momen beku: di mana pun momen beku itu secara implisit clone() s, pembungkus mutabilitas ini malah akan secara implisit mengubah referensi internalnya ke nilai momen baru yang tidak dapat diubah. Ini juga dapat membantu memudahkan transisi bagi orang-orang yang menggunakan momen dalam basis kode besar.
  2. Saya akan bersedia membantu memikirkan masalah potensial dan menerapkan kekekalan pada saat 3, jika diinginkan.
  3. js-joda akan langsung mem-porting JSR-310 ke dalam JavaScript menggunakan lisensi BSD .

@butterflyhug - Terima kasih telah membangun momen beku! Saya senang ketika saya menemukan itu, tetapi khawatir tentang memperkenalkan ketergantungan dari proyek saya ke momen beku, mengingat bahwa jika dukungan dihentikan, perubahan dari momen yang tidak dapat diubah menjadi momen yang dapat diubah akan menjadi pekerjaan besar dalam kode saya. Jika tujuan Anda adalah untuk mendapatkan umpan balik dan Anda secara aktif mendukungnya, saya lebih nyaman melakukannya. :-)

Saya tidak tahu berapa banyak orang lain yang mungkin memiliki proses berpikir yang sama.

Saya ingin tahu apakah orang-orang di sini berpikir bahwa kekekalan harus dieksplorasi bersama dengan gagasan untuk memutus ketergantungan pada objek Date (atau bahkan menambahkan semacam evaluasi malas) untuk alasan kinerja.

Saya akan menyarankan untuk mengambil sesuatu selangkah demi selangkah, @schmod. Ini sudah (tampaknya) perubahan besar

@RobertMcCarter Ya, saya berencana untuk mendukung momen beku di masa mendatang, kecuali/sampai beberapa opsi untuk kekekalan diimplementasikan di perpustakaan inti - sebagian besar karena saya pribadi menggunakannya untuk beberapa hal yang saya harapkan mempertahankan untuk sementara waktu. Karena itu, kasus penggunaan saya tidak menjangkau ekosistem Momen penuh, jadi saya mengandalkan umpan balik dan penggunaan dari orang lain untuk membantu mengidentifikasi apa yang penting.

+1 untuk kekekalan, setelah setengah jam dihabiskan untuk mencari tahu apa yang terjadi dengan aplikasi saya setelah pertama kali menggunakan endOf(). Memang saya tidak membaca dokumen dengan cermat, saya hanya berasumsi metode dengan nama itu akan mengembalikan akhir bulan misalnya, dan membiarkan instance momen tidak terpengaruh. Sejujurnya ini mengejutkan dan saya merasa konyol bahwa itu tidak terjadi seperti ini atau mungkin kepala saya terlalu terbiasa dengan -menurut pendapat saya- manfaat besar dari memiliki -sebagian besar- API yang tidak dapat diubah

+1 untuk kekekalan :)

Saya tidak peduli tentang kekekalan, tinggalkan perpustakaan yang luar biasa ini!

@es6Test Atas dasar apa Anda tidak setuju dengan kekekalan? Apakah Anda memiliki alasan konkret selain penolakan terhadap perubahan?

+1
Saya pikir itu akan memudahkan penggunaan perpustakaan jika itu tidak dapat diubah, kode saya penuh dengan metode .clone() dan terkadang mutabilitas memprovokasi sangat sulit untuk menemukan bug.

+1 Tolong, lebih banyak kekekalan ^_^

@danpantry Setelah membuat beberapa aplikasi lagi, saya berubah pikiran. Saya lebih suka kekekalan.

Tetapi saya ingin tetap memiliki beberapa vars yang dapat diubah, saya cukup sering ingin menambahkan hari ke momen dan saya tidak ingin harus membuat lebih banyak vars untuk menahan hasilnya.

@es6Test Cukup gunakan let jika Anda _benar-benar_ tidak menyukainya?

let date = moment()
// with immutability
date = date.add(5)

Saya mendukung kekekalan juga. Itulah salah satu fitur dari library datetime Python yang benar-benar membuatnya bersinar. Anda dapat melempar objek tanpa khawatir tentang sesuatu yang memodifikasinya, seperti halnya dengan string karakter.

Di dunia React / Redux, kekekalan sangat penting. Saya sudah mengalami beberapa masalah degil karena momen pada dasarnya tidak dapat diubah. Kinerja tidak relevan di sini karena dapat dikurangi. Pustaka ImmutableJs dari Facebook membuktikan bahwa immutable dapat dilakukan tanpa mengorbankan kinerja.

Saya juga akan memberi +1 pada kekekalan sepanjang jalan. Anda tidak mendapatkan manfaat dari kekekalan sampai saat itu, jadi tidak ada gunanya melakukan setengah jalan.

Kekekalan dan pemrograman fungsional lebih banyak digunakan sekarang daripada sebelumnya (dan saya menyukainya). Saya akan menawarkan waktu saya sendiri untuk berkontribusi pada inisiatif ini. Kontributor silakan hubungi saya dan beri tahu saya bagaimana saya bisa membantu.

Tim ingin memberikan pembaruan tentang ini karena kami memiliki begitu banyak minat.

Saat ini, kami ingin Anda tahu bahwa kami telah mendengar kekhawatiran Anda. Seluruh tim pengelola setuju bahwa jika kami menulis perpustakaan dari awal, kami akan memilih untuk membuatnya tidak dapat diubah. Namun, tidak seperti itu sekarang.

Saat ini, kami memiliki 4 juta unduhan NPM per bulan, bersama dengan jumlah pengguna yang tak terhitung yang mengandalkan untuk mendapatkan momen melalui saluran lain. Semua pengguna ini memiliki kode yang mengharapkan momen dapat berubah seperti sekarang ini. Selain itu, kami memiliki banyak plugin yang mengandalkan momen yang bisa berubah.

Kodenya cukup mudah untuk ditulis, tetapi kebutuhan dukungan untuk perubahan semacam ini sulit dilakukan karena tim kecil melakukan ini di waktu luang kami. Yang mengatakan, kami bersedia untuk mempertimbangkannya. Kami bertanya-tanya meskipun:

  • Mengapa plugin momen beku tidak memenuhi kebutuhan Anda?
  • Apakah Anda hanya memerlukan API yang tidak dapat diubah (API yang selalu mengembalikan klon), atau apakah kami karena alasan tertentu perlu benar-benar tidak mengubah objek secara internal?
  • Apakah menambahkan API kedua yang tidak dapat diubah ke kode saat ini memenuhi kebutuhan Anda?

Masalah dengan plugin momen beku adalah bahwa itu ikut serta, bukan keluar. Setiap
moment() membutuhkan .freeze() agar tidak berubah.

Inti dari kekekalan adalah ketika saya memiliki objek X, saya tahu itu
kecuali saya secara eksplisit membuatnya bisa berubah, itu harus tahan terhadap perubahan.
Fungsi publik apa pun yang memungkinkan saya mengubah objek secara internal tanpa
mutabilitas eksplisit bermasalah.

Saya pikir satu solusi adalah melakukan beberapa hal:

  1. Tambahkan API kedua yang tidak dapat diubah ke kode saat ini
  2. Miliki pengaturan momen global () di mana jika diatur ke mode tidak berubah, semua
    moment() instance yang dibuat tidak dapat diubah, jika panggilan yang dapat diubah dicoba,
    tidak akan bermutasi dan sebagai gantinya kesalahan dengan pesan yang sesuai untuk digunakan tidak dapat diubah
    panggilan api.

Itu saya pikir akan memuaskan semua orang. Bagaimana menurutmu?

Pada Senin, 23 Mei 2016 pukul 12:11, Maggie Pint [email protected]
menulis:

Tim ingin memberikan pembaruan tentang ini karena kami memiliki begitu banyak
minat.

Saat ini, kami ingin Anda tahu bahwa kami telah mendengar kekhawatiran Anda. NS
seluruh tim pengelola setuju bahwa kami menulis perpustakaan dari
bawah ke atas, kami akan memilih untuk membuatnya berubah. Namun, bukan itu caranya
itu sekarang.

Saat ini, kami memiliki 4 juta unduhan NPM per bulan, bersama dengan
jumlah pengguna yang tak terhitung yang mengandalkan untuk mendapatkan momen melalui yang lain
saluran. Semua pengguna ini memiliki kode yang mengharapkan momen dapat berubah sebagai
itu hari ini. Selain itu, kami memiliki banyak plugin yang mengandalkan momen
yg mungkin berubah.

Kodenya cukup mudah untuk ditulis, tetapi dukungannya membutuhkan semacam ini
perubahan sulit dilakukan sebagai tim kecil yang melakukan ini di cadangan kami
waktu. Yang mengatakan, kami bersedia untuk mempertimbangkannya. Kami bertanya-tanya meskipun:

  • Mengapa plugin momen beku tidak memenuhi kebutuhan Anda?
  • Apakah Anda hanya memerlukan API yang tidak dapat diubah (API yang selalu mengembalikan a
    kloning), atau apakah kita karena alasan tertentu perlu benar-benar tidak mengubah
    benda?
  • Akan menambahkan API kedua yang tidak dapat diubah ke kode saat ini memenuhi
    kebutuhan?


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung atau lihat di GitHub
https://github.com/moment/moment/issues/1754#issuecomment -221062274

Eric Lau dari akun Gmail.

Terima kasih telah menanggapi @maggiepint.

  1. Beberapa masalah dengan plugin momen beku: ini bukan default, memerlukan kerja ekstra untuk digunakan, kecil kemungkinannya akan dipertahankan secara aktif, asumsi saya adalah bahwa ia memiliki hit kinerja (mungkin sangat kecil) di atas sesuatu yang sebelumnya dibangun sebagai tidak berubah. Saya pikir masalah terbesar adalah lupa menggunakannya, terutama pada proyek yang lebih besar dengan banyak insinyur.
  2. API harus bebas efek samping. Mengembalikan klon itu bagus tetapi jika Anda juga memodifikasi objek asli itu akan menjadi efek samping. Kode berikut tidak boleh mengubah awal saat mendeklarasikan akhir:
start = moment();
end = start.add(10, 'minutes');
  1. Apakah maksud Anda memiliki fungsi seperti 'immutableAdd' selain 'add'? Jika demikian maka ya secara teknis, terutama jika Anda membuat pembungkus untuk menggunakan fungsi yang tidak dapat diubah menggunakan nama yang sama:
import "moment/immutable";
start = moment();
end = start.add(10, 'minutes'); // immutable version of add

Menurut pendapat saya, pendekatan ini cocok untuk peningkatan yang anggun bagi mereka yang ingin menggunakan API yang tidak dapat diubah—kode yang ada akan tetap berfungsi, tidak ada yang dipaksa, dan memerlukan lebih sedikit perubahan bagi mereka yang ingin menggunakan API yang tidak dapat diubah.

Kami memiliki niat untuk membuat efek samping kode gratis. Pola dasarnya adalah menghubungkan ke fungsi saat ini, meminta mereka memanggil klon, dan kemudian beroperasi pada klon itu.

Namun secara teknis, jika Anda membuat kode yang benar-benar tidak dapat diubah, objek harus dibuat dengan nilai yang tidak akan berubah. Melakukan hal itu akan meningkatkan kesulitan dalam membuat perubahan ini. Jauh lebih mudah untuk memanggil klon dan kemudian melakukan apa yang kami lakukan sebelumnya.

Saya mendukung ide Drew:

impor "momen/tidak berubah";
mulai = momen();
end = start.add(10, 'menit'); // versi add yang tidak dapat diubah

Itu akan bagus karena itu tidak dapat diubah dan tidak ada perubahan pada
nama fungsi.

Pada Senin, 23 Mei 2016 pukul 12:53, Maggie Pint [email protected]
menulis:

Kami memiliki niat untuk membuat efek samping kode gratis. Dasar
pola akan menghubungkan ke fungsi saat ini, minta mereka memanggil klon,
dan kemudian beroperasi pada klon itu.

Namun secara teknis, jika Anda membuat kode yang benar-benar tidak dapat diubah, objek
harus dibangun dengan nilai-nilai yang tidak akan berubah. Melakukannya akan
meningkatkan kesulitan dalam membuat perubahan ini sekalipun. Jauh lebih mudah untuk
panggil clone dan kemudian lakukan apa yang kami lakukan sebelumnya.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung atau lihat di GitHub
https://github.com/moment/moment/issues/1754#issuecomment -221076796

Eric Lau dari akun Gmail.

@ericlau-solid

  1. Miliki pengaturan momen global () di mana jika diatur ke mode tidak berubah, semua
    moment() instance yang dibuat tidak dapat diubah, jika panggilan yang dapat diubah dicoba,
    tidak akan bermutasi dan sebagai gantinya kesalahan dengan pesan yang sesuai untuk digunakan tidak dapat diubah
    panggilan api.

Ini akan rusak jika 2 pustaka pada halaman mengharapkan perilaku momen yang berbeda. Misalnya Anda menggunakan datepicker, yang mengharapkan momen yang bisa berubah, dan kode Anda sendiri mengharapkan momen yang tidak bisa diubah -- itu tidak akan berfungsi.

Memiliki api yang tidak dapat diubah (ala momen beku)

Ini juga tidak sempurna, karena tidak ada plugin momen yang akan bekerja dengannya. Sebenarnya, tidak ada cara untuk memperkenalkan kekekalan DAN menjaga semua plugin yang ada tetap berfungsi. Plugin tidak akan berfungsi sama sekali, atau tidak berfungsi dengan momen yang tidak dapat diubah, sebelum seseorang menghabiskan waktu untuk membuatnya berfungsi.

impor "momen/tidak berubah";

Jadi ini pada dasarnya mengusulkan perpustakaan yang berbeda dengan antarmuka yang serupa. Tentu, itu tidak akan merusak kode tetapi kemungkinan akan menyebabkan kebingungan dan membuat beberapa proyek menginstal 2 versi (misalnya datepicker akan mengambil versi yang dapat diubah, dan kode Anda akan mengambil yang tidak dapat diubah).

Opsi terbaik adalah membuat API seperti yang sekarang, tetapi dengan objek yang tidak dapat diubah. Sebuah garpu mungkin beres. Begitulah cara perangkat lunak bebas.

Opsi "tambahkan API kedua / terbitkan submodule" akan menjadi yang terbaik untuk kompatibilitas, karena pengembang akan dapat memutakhirkan kode mereka secara bertahap. Jika memungkinkan, arti dari moment() (via import moment; di module-land, atau moment global di browser build) tidak boleh berubah sama sekali, karena ada ton kode warisan di luar sana.

IMO, solusi yang memungkinkan yang berikut ini ideal:

import moment from 'moment';
import {immutable as immoment} from 'moment';

var a = moment(); // mutable moment
var b = moment().immutable(); // immutable moment
var c = immoment(); // also an immutable moment; shorthand

Bukan perpustakaan yang berbeda, tapi ya -- memiliki dua jenis momen yang terpisah dan berbeda. Dengan asumsi bahwa objek momen yang dapat berubah dan tidak dapat diubah berbagi sejumlah besar kode "di bawah tenda", ukuran perpustakaan tidak perlu meningkat banyak untuk pengembang yang perlu menggunakan kedua sintaks. Jika aplikasi hanya menggunakan satu sintaks, pengocokan pohon dapat digunakan untuk menghasilkan build yang dioptimalkan.

Forking library berpotensi menggandakan ukuran kode yang harus dimuat oleh sebagian besar pengembang, yang tidak diinginkan untuk sebagian besar aplikasi web.


Saya tidak berpikir bahwa itu akan menjadi ide yang baik untuk mengasumsikan bahwa plugin apa pun akan bekerja dengan momen yang tidak dapat diubah "di luar kotak," dan tidak akan menganggap itu sebagai persyaratan yang masuk akal.

Saya juga tidak berpikir itu persyaratan/asumsi yang masuk akal untuk API yang bisa berubah dan yang tidak bisa diubah menjadi identik. Kita harus berusaha untuk membuat jalur pemutakhiran semulus mungkin, tetapi tidak harus mengunci diri kita sendiri ke dalam sintaks yang canggung.


Saya juga berpikir ada banyak ruang untuk debat/argumen tentang seperti apa API "tidak dapat diubah". Pola pembangun? Instansiasi konstruktor? Nilai objek? Terapkan API saat ini, tetapi apakah ada metode "penyetel" yang mengembalikan klon?

Satu permintaan saya adalah bahwa API baru harus jelas dan tidak ambigu tentang momen seperti apa yang sedang kita kerjakan. IMO, freeze gagal dalam tes itu, dan menawarkan sedikit perlindungan selain memanggil clone() setiap kali saya melewatkan momen.

Jadi ini pada dasarnya mengusulkan perpustakaan yang berbeda dengan antarmuka yang serupa. Tentu, itu tidak akan merusak kode tetapi kemungkinan akan menyebabkan kebingungan dan membuat beberapa proyek menginstal 2 versi (misalnya datepicker akan mengambil versi yang dapat diubah, dan kode Anda akan mengambil yang tidak dapat diubah).

Bukan perpustakaan terpisah, hanya pembungkus tipis di sekitar perpustakaan yang sama. Hanya perlu satu versi saat diinstal. Anda dapat mengimpor 'momen/tidak dapat diubah' dan datepicker dapat mengimpor 'momen' dalam proyek yang sama tanpa masalah.

Mungkin ada masalah dalam berinteraksi dengan plugin yang mengambil atau mengembalikan momen jika mereka belum memperbarui untuk menangani momen yang tidak dapat diubah.

Katakanlah Anda memberikan momen yang tidak dapat diubah ke sebuah plugin yang, saat ini, memperlakukannya sebagai dapat diubah. Sampai plugin diperbarui, perlu ada cara untuk mengonversi menjadi bisa berubah sebelum waktu diberikan ke plugin. Idealnya itu akan ditinggalkan setelah pengelola proyek memiliki waktu untuk memanggang untuk mendukung kekekalan. Mungkin juga perlu ada cara untuk mendeteksi kekekalan (untuk penulis plugin).

Di sisi lain perpustakaan yang memperbarui untuk menggunakan antarmuka yang tidak dapat diubah, dan mengembalikan momen yang tidak dapat diubah kepada pengguna, dapat membuang mereka yang tidak menggunakan kekekalan dan tidak mengharapkan momen yang tidak dapat diubah. Saya percaya ini juga dapat ditangani dengan metode konversi yang tidak digunakan lagi. Plugin harus mengembalikan momen dengan jenis yang sama seperti yang diteruskan.

@maggiepint ya saya mengerti maksud Anda, tetapi saya pikir itu mungkin lompatan yang terlalu besar untuk dilakukan. Secara pribadi saya akan baik-baik saja dengan pendekatan yang hanya clone di balik tirai. Terutama saat kekusutan sedang dikerjakan.

@tacomanator itulah yang ingin saya lakukan juga. Mengulangi semuanya agar benar-benar tidak berubah secara internal tidak terlalu bisa dipertahankan.
Saya hanya tidak tahu apakah karena alasan tertentu orang-orang MENGINGINKAN itu.

@schmod Bisakah Anda menjelaskan secara singkat mengapa menurut Anda freeze adalah API yang jelas dan tidak ambigu?

Jika nama fungsi terlalu lucu, saya akan dengan senang hati mempertimbangkan argumen untuk mengganti nama metode Momen Beku sebagai masalah pada repo itu. Di sisi lain, jika menurut Anda tidak mungkin untuk mengonversi dari yang dapat berubah menjadi tidak dapat diubah (dan kembali), maka saya menduga itu mungkin akan mendorong beberapa diskusi di sini - meskipun perhatikan bahwa saya juga bersedia mengambil Momen Beku ke arah itu jika kita mendapatkan konsensus kasar bahwa itu akan menjadi API yang lebih baik.

@maggiepint Apakah saya benar dalam membaca "tambahkan API kedua yang tidak dapat diubah ke kode saat ini" karena pada dasarnya menggabungkan sebagian atau seluruh Momen Beku dengan perpustakaan inti? Jika itu akan membantu, saya akan dengan senang hati membantu memigrasikan Momen Beku atau beberapa idenya ke dalam organisasi momen (baik sebagai plugin resmi atau sebagai bagian dari pustaka inti) dan membantu pemeliharaannya dalam konteks baru itu.

@butterflyhug Anda mengatakan persis apa yang dipikirkan @ichernev . Dia condong ke plugin resmi yang dikirimkan bersama perpustakaan. Mungkin kita bisa mengoordinasikan ini di Gitter di beberapa titik? Saya harus pergi selama tiga hari untuk urusan bisnis, jadi ketersediaan saya terbatas. Orang-orang lainnya harus ada di sekitar.

@butterflyhug

Saya pikir freeze adalah nama yang bagus, itu hanya menyebalkan harus ingat untuk menggunakannya setelah _setiap permintaan_ saat.

Saya juga berpikir bahwa import 'moment/immutable' memiliki masalah yang sama, mudah untuk melupakannya.

Sejujurnya, Anda mengikuti semver, saya pikir pendekatan yang benar adalah membuat semuanya menggunakan _by default_ yang tidak dapat diubah dan melepaskan perubahan ini sebagai versi utamanya sendiri, dengan rencana untuk tidak lagi mendukung versi yang lebih lama setelah jangka waktu (12 bulan?). Fitur / perbaikan baru dapat digabungkan ke dalam kedua trek, tidak dapat diubah dan dapat diubah, dengan rencana migrasi yang diberikan kepada pengguna menggunakan versi yang dapat diubah.

Setelah 12 bulan yang disebutkan di atas, versi lama akan _masih_ berfungsi, tetapi tidak akan menerima TLC apa pun.

Tentu saja, ini banyak overhead, tapi saya pikir akan lebih baik untuk melakukan perubahan ini dengan benar daripada mencoba dan memalsukannya untuk kepentingan kompatibilitas ke belakang. Itu juga membuat perubahan jauh lebih rumit yang dapat menghalangi minat dari tim pengembangan inti. Saya tidak tahu.

Kelemahan potensial lain dari pendekatan ini adalah di mana pengguna menggunakan skrip ini dari CDN dan tidak menentukan versi eksplisit (untuk alasan apa pun), yang dapat menyebabkan situs mereka rusak jika API yang kompatibel dengan versi sebelumnya dirilis. Yang bisa saya katakan hanyalah "Sudah saya katakan", tetapi saya mengerti bahwa ini mungkin bukan risiko yang dapat diterima untuk saat ini.

Memiliki dua versi perpustakaan yang sama hanya akan menjadi masalah jika Anda mengandalkan objek global dan sebenarnya tidak ada cara lain selain terus menggunakan freeze() .


TLDR sepertinya masalah yang Anda coba selesaikan diselesaikan dengan semver, yang sudah Anda gunakan. Mengapa tidak menggunakannya sebagaimana mestinya? Versi utama untuk melanggar perubahan. Satu-satunya kesempatan istirahat ini adalah ketika Anda mengandalkan variabel global moment & menggunakan CDN, tetapi perubahan apa pun yang kami buat di sini akan tetap merusaknya

Suara saya juga pada rilis semver dan 3.0 yang tidak dapat diubah.

Saya tidak keberatan dengan nama freeze , tetapi secara inheren bermasalah bahwa sulit untuk membuat asumsi yang aman tentang apakah suatu momen dibekukan atau tidak. ( Object.freeze() memiliki masalah serupa)

Momen yang tidak dapat diubah seharusnya tidak dapat dibekukan, dan tidak boleh ada keraguan tentang apakah itu beku atau tidak. Ini dapat dicapai melalui varian ketat dari pola builder (yaitu objek _only_ memiliki setter hingga .build() dipanggil, setelah itu _only_ memiliki getter), atau memiliki momen menjadi "beku" segera setelah itu dipakai, dengan semua setter mengembalikan klon.

Sebagai contoh:

/* BUILDER PATTERN */
var bldr = moment.immutable()
  .hours(5)
  .minutes(30)
  .seconds(25);

bldr.hours();  // throws exception.  builder has no getters

var time = bldr.build();

time.hours(); // 5
time.hours(6); // throws, OR returns a clone

/*  A more explicit variant:  */
var bldr = moment.immutable()
  .setHours(5);

bldr.getHours; // undefined

var time = bldr.build();
time.getHours(); // 5
time.setHours;   // undefined
/* VALUE OBJECT */
var time = moment.immutable()   // 00:00:00
  .hours(5)       // new object => 05:00:00
  .minutes(30)    // new object => 05:30:00
  .seconds(25);   // new object => 05:30:25

/*  Same thing, but more efficient:  */
var time2 = moment.immutable(5,30,25); // 05:30:25

time.hours();   // 5
time.hours(6);  // new object => 06:30:25

Contoh pertama sangat mirip dengan java, tetapi juga menyisakan sedikit ambiguitas tentang bagaimana momen dibangun, dan apa yang dapat Anda lakukan dengannya. Ini juga menyediakan jalur yang efisien dan intuitif untuk membangun momen baru dengan sedikit overhead, dan mengikuti cara kebanyakan orang saat ini menggunakan momen.

Saya lebih suka memiliki setter pada momen yang dibangun dengan pengecualian, karena perilaku ini akan semakin mengurangi ambiguitas (dengan mengorbankan verbositas), dan memaksa pengembang untuk mengakui setiap kali mereka membuat momen baru.

Contoh kedua sepertinya memiliki lebih banyak overhead, karena kita membuat (dan membuang) banyak objek. Tapi, ada banyak ruang untuk optimasi. GC modern cukup bagus; evaluasi malas bisa membantu; kita bisa membuat objek Moment seringan mungkin (meninggalkan Date mendasarinya), dll. (Untuk beberapa perbandingan, pola ini tidak berbeda dengan cara penanganan string dalam JavaScript)


Saya penggemar semver, tetapi kasus penggunaan browser membuat perubahan menjadi bermasalah, karena tidak mungkin memiliki dua versi momen di halaman yang sama tanpa pemuat modul.

Seperti yang disebutkan sebelumnya, ada _lot_ kode lama di luar sana yang bergantung pada Momen. Paling tidak, kita membutuhkan rilis yang mendukung kedua pola tersebut, untuk memungkinkan periode transisi yang mulus.

+1 untuk metode yang dapat dikomposisi yang mengembalikan momen baru. Aku bahkan tidak peduli jika mereka tidak berubah. Beri saya komposisi, jadi saya bisa menghubungkan metode bersama-sama, atau menetapkan momen bermutasi dalam satu baris (bukan 2).

@alexyuly mengapa klon tidak berfungsi untuk Anda? Jika Anda ingin menulis sebaris, Anda dapat melakukan sesuatu seperti:

var a = moment();
var b = a.clone().subtract(1, 'week').startOf('day');

Atau terserah.

@maggiepint Yah saya merasa bodoh, sepertinya Anda bisa membuat metode selama ini. Terima kasih atas tipnya. Mungkin membuatnya sedikit lebih jelas di dokumen? misalnya http://momentjs.com/docs/#/manipulating/start -of/ <- tidak menyebutkan nilai pengembalian apa pun.

Sedikit pembaruan - posting blog ini adalah posisi SAYA tentang masalah ini saat ini: https://maggiepint.com/2016/06/24/why-moment-js-isnt-immutable-yet/

Saya tidak berbicara untuk anggota tim lainnya, tetapi mereka telah melihatnya, dan saya biasanya mengatakan kita semua berada di tempat yang sama.

@maggiepint poin yang bagus dan sangat valid

Terima kasih untuk ini. Kekekalan adalah raja di redux, jadi saya pasti akan beralih ke js-joda. Saya mungkin masih menyimpan momen untuk waktu yang relatif.

Eric Lau - Gmail

Pada Jumat, 24 Jun 2016 pukul 11:12 -0700, "Maggie Pint" [email protected] menulis:

Sedikit pembaruan - posting blog ini adalah posisi SAYA tentang masalah ini saat ini: https://maggiepint.com/2016/06/24/why-moment-js-isnt-immutable-yet/

Saya tidak berbicara untuk anggota tim lainnya, tetapi mereka telah melihatnya, dan saya biasanya mengatakan kita semua berada di tempat yang sama.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub, atau matikan utasnya.

Beberapa bug/kebingungan yang lebih khas yang disebabkan oleh mutasi: http://stackoverflow.com/questions/26131003/moment-js-start-and-end-of-given-month

+1 untuk ini tetapi sebenarnya dengan Redux saya menemukan ini sebagai masalah kecil yang mengejutkan karena saya tidak memasukkan instance Moment ke objek status Redux sama sekali. Hanya string tanggal atau stempel waktu dan saya menggunakan Moment dalam metode render hanya untuk mengonversi string tanggal ke string lain.

Saya melakukan ini terutama karena mudah untuk membuat serial dan deserialize keadaan tanpa kerja ekstra tetapi juga menyembunyikan mutasi dengan baik dari React dan Redux.

Melakukan yang terbaik untuk memberi Anda pembaruan tentang yang satu ini akhir pekan ini. Kami punya rencana, tapi saya harus memastikan semuanya akan berhasil sebelum saya berkomitmen untuk itu. Sayangnya saya pindah dari Minneapolis ke Seattle minggu depan, jadi ini mungkin melambat untuk sementara waktu, tetapi saya ingin memajukannya.

Pembaruan kecil dalam persiapan untuk pembaruan yang lebih besar, karena saya perhatikan bahwa posting blog itu masih mendapatkan beberapa lalu lintas. Saat ini saya sedang mengerjakan ulang momen untuk menggunakan Babel. Ini akan membuat kami memasukkan plugin @butterflyhug telah sangat membantu kami dengan ini. Selain itu, saya bertemu dengan John-David Dalton dari LoDash (kami berdua bekerja di Microsoft) untuk membahas strategi saat membawa plugin resmi, karena dia sudah melakukannya dengan fungsi LoDash. Posting blog panjang dan RFC segera hadir.

@maggiepint saat membuat momen beku didukung secara resmi, apakah Anda berencana menangani https://github.com/WhoopInc/frozen-moment/issues/20?

Saya pikir pendekatan kekekalan ini cukup baik selama setiap panggilan ke moment() mengembalikan momen beku secara default, dan devs tidak harus ingat menelepon .freeze() setiap waktu.

@gabrielmaldi Pertanyaan bagus. Saya sedang menulis RFC (harus dilakukan kapan saja sekarang), dan ya, itu adalah tujuan eksplisit saya untuk memberikan cerita yang lebih baik untuk penggunaan yang tidak dapat diubah. Proposal saya sejalan dengan komentar saya di WhoopInc/frozen-moment#20, dengan mempertimbangkan metode statis. Saya akan memposting tautan ke RFC saya di sini dan di edisi itu ketika saya membuka PR saya terhadap repo RFC, dan kami pasti akan menyambut umpan balik komunitas tentang proposal tersebut pada saat itu.

Saya sudah selesai menulis draft RFC dan membuka PR .

Ini adalah dokumen yang cukup panjang, sebagian karena masih ada beberapa pertanyaan yang belum terjawab tentang bagaimana kami ingin memberikan fungsionalitas ini kepada pengguna, jadi saya mencoba menyoroti pro dan kontra dari berbagai pendekatan di sana. Tapi saya pikir ide implementasinya cukup solid, jadi saya ingin mendengar dari orang-orang di sini jika Anda memiliki keraguan tentang API yang menghadap pengguna yang diusulkan .

Ringkasan eksekutif RFC dengan pertanyaan utama kami yang harus dijawab: https://maggiepint.com/2016/07/16/immutability-its-happening/

@maggiepint saya mencoba memposting komentar di artikel itu, tetapi karena alasan tertentu tertelan. Inilah yang saya tulis:


Kekhawatiran terbesar saya dengan perubahan ini adalah bahwa mereka menanggapi bagian komunitas yang vokal dan ekspresif secara tidak proporsional - menghindari benteng yang tenang dari pengembang biasa yang bahkan tidak menyadari diskusi ini sedang berlangsung.

Utas GitHub bukanlah mikrokosmos komunitas pengembangan yang lebih luas. Situs ini mengalami bias partisipasi yang sama seperti banyak forum di web, dan bias terhadap jenis pengembang tertentu: terlibat secara intelektual dengan teori komputasi; tertarik pada ide daripada aplikasi; dan berani saya bahkan mengatakan sosial cenderung untuk menggalang tren populer. Pengembang ini secara alami tertarik pada penyebab filosofis selebritas seperti kekekalan dan pemrograman fungsional, dan memiliki akses lebih dekat kepada Anda daripada grup lain mana pun. Mereka akan menjadi suara paling keras di ruangan itu, dan mereka akan menuntut perubahan ini - tapi bagaimana dengan dunia yang lebih luas?

Dunia yang lebih luas menginginkan Hal yang Berfungsi. Ia ingin tahu bahwa perpustakaan yang saat ini digunakannya akan terus menerima pembaruan - setidaknya perbaikan bug, tetapi idealnya peningkatan kecil yang membuat hidup mereka lebih baik. Tetapi tidak dikatakan demikian, karena tidak aktif mencari forum-forum ini, dan karena dibutuhkan kulit tebal untuk berbicara menentang tren.

Jika Anda menginginkan perubahan ini, saya pikir Anda perlu membuat kasus yang sangat jelas kepada orang-orang ini mengapa perubahan ini akan membuat hidup mereka lebih baik; mengapa mereka harus meningkatkan; mengapa mereka tidak perlu khawatir proyek warisan mereka tidak akan menerima perbaikan bug tidak langsung; dan pada dasarnya - hal-hal apa yang sekarang dapat mereka lakukan yang tidak dapat mereka lakukan saat ini.

Saya juga berpikir Anda juga harus sangat berhati-hati untuk memvalidasi pentingnya perubahan ini secara nyata. Saya ingin tahu apakah Anda harus merilis perubahan ini sebagai plugin atau pembungkus, dan memantau penyerapannya dengan hati-hati selama beberapa bulan sebelum menggabungkannya ke dalam trunk. Jika kekekalan telah direpresentasikan secara berlebihan sebagai perhatian khusus, Anda akan menemukan cara untuk memuaskan pengguna vokal ini tanpa mengubah arah perpustakaan secara keseluruhan.

Sebagai pengguna pertama kali saya berakhir di sini setelah beberapa waktu hilang dengan startOf endOf. Metode-metode ini secara mengejutkan bermutasi!

+1 untuk kekekalan penuh

Mungkin solusi lain adalah dengan membuatnya sangat jelas bahwa objek di momentjs bisa berubah . Dokumentasi memang menyebutkannya di bagian kloning, tetapi TIDAK cukup menonjol.

Solusi lain, Jika Anda ingin mutabilitas, gunakan konsep Berorientasi Objek dan buat pembuatan objek menggunakan kata kunci BARU vs pola pabrik momen ().

Dunia yang lebih luas menginginkan Hal yang Berfungsi.
...Anda perlu membuat kasus yang sangat jelas kepada orang-orang ini mengapa perubahan ini akan membuat hidup mereka lebih baik

Semua orang yang saya saksikan menjadi baru di momen jatuh ke dalam jebakan "momen" yang bermutasi.
Bahkan setelah 3 tahun menggunakan momen saya masih harus mengatakan pada diri sendiri "oh sial Anda menggunakan .startOf here .. lebih baik periksa dua kali jika Anda memerlukan salinan".

Perilaku saat ini tidak intuitif dan ini sudah lama tertunda.
Cobalah untuk membuat array.filter/map bermutasi dan lihat betapa menyenangkannya itu.

Tentang...
Kinerja/Memori: Saya tidak pernah merantai lebih dari 2 fungsi dalam satu momen dan biasanya .set().get()
Pseudo-Immutability: Ini akan memakan banyak banyak generasi sampai java-pass-by-ref-gen keluar.

Saya suka ide @AdamHess tentang memilih apakah Anda mencari OOP atau kekekalan.

Dua sen saya tentang mengapa kita menjadi bingung adalah ini: mengembalikan nilai. Jika moment.add('1', 'days') kembali tidak terdefinisi, seperti fungsi yang bisa berubah di JS umumnya, maka kebingungan akan hilang. Mengembalikan objek yang sama, setidaknya bagi saya, menyiratkan bahwa saya memiliki salinan baru. Tentu saja, itu akan mematahkan kemampuan rantai.

Saya pikir ada kemungkinan rendah mengenai masalah penggunaan memori untuk lebih banyak pengembang (kecuali untuk kasus penggunaan khusus). Mutabilitas Moment telah menggigitku. Tanggal harus diperlakukan sebagai nilai seperti string atau angka.

+1 untuk tidak dapat diubah secara default

Omong-omong, masalah yang sama ada untuk PHP. Apakah Anda ingin menjadi seperti PHP?! 😆

Di PHP, mereka menyelesaikannya dengan memberikan DateTimeImmutable (selain normal DateTime ).

Jika kita tidak mengubah perilaku default menjadi tidak dapat diubah, setidaknya kita harus mempertimbangkan API alternatif kelas satu seperti imoment / momenti (atau apa pun). Saya benar-benar akan selalu menggunakannya (melalui API yang bisa berubah) dan saya berharap perpustakaan lain yang saya gunakan akan menggunakan versi/API yang tidak dapat diubah juga.

Saya memilih kekekalan juga, saya bersedia membantu menerapkan jika itu rencananya. Saya sudah mengalami masalah mutabilitas ketika melakukan penambahan dan pengurangan, yang membuatnya lebih membingungkan, adalah bahwa metode ini mengembalikan instance karena chaining.

Omong-omong, bagaimana dengan durasi kloning? Apa cara terbaik untuk melakukan itu, tidak dapat menemukan yang tidak terasa hacky.

@ngerritsen Saya percaya opsi terbaik yang tersedia adalah moment.duration(existingDuration) .

Re: implementasi, #3548 masih PR aktif. Mudah-mudahan tidak banyak pekerjaan tingkat kode yang tersisa, tetapi tidak ada salahnya untuk memiliki lebih banyak mata untuk memvalidasi perubahan besar. Kami juga perlu mengerjakan dokumentasi dan lain-lain sebelum kami dapat melakukan perubahan versi utama, yang akan diperlukan untuk merilis perubahan seperti ini. Jika Anda ingin membantu dengan daftar ini, saya yakin kami akan menghargainya. 😀

Hanya menghabiskan satu jam mencoba mengidentifikasi bug halus yang disebabkan oleh .startOf() mengubah tanggal asli... Terima kasih atas kerja kerasnya, momentjs melakukan pekerjaan yang bagus dengan menunjukkan cara membuat lib tanggal yang sangat baik untuk JS, tapi saya beralih to date-fns karena sifat yang sangat halus dari jenis bug ini dan karena setelah pengenalan saya pada beberapa konsep umum FP (sebagian besar berkat React, Redux dan ELM) saya mulai menghargai manfaat umum dari kekekalan.

Untuk apa nilainya, lodash telah mengikuti lebih banyak pendekatan FP dengan lodash/fp. Saya sarankan untuk melihat cara lodash/fp diimplementasikan karena mereka membungkus fungsi yang ada daripada harus menyelesaikan penulisan ulang semuanya. Orang-orang Lodash juga sangat memperhatikan kinerja.

Saya juga setuju dengan @mull , masalah sebenarnya adalah karena API

Sementara namespace moment.frozen sedang dikerjakan, saya akan merekomendasikan --seperti yang disarankan poster sebelumnya-- untuk hanya menggunakan date-fns .

Baru saja memperbaiki bug lain karena momen yang bisa berubah

Terkait secara tangensial, akan luar biasa jika 3.0 dapat pindah ke kelas ES6:

let mom1 = new Moment();
let mom2 = Moment.parse('2019-03-01T14:55');
// etc

Langkah seperti itu juga bisa memandu diskusi kekekalan. Saya akan mengatakan semua metode harus tidak berubah dengan satu pengecualian. Metode yang disebut .set('minute/hour/year/etc', 18) .

Saya baru saja mulai menggunakan Momen, dan _mengerikan_ bahwa perpustakaan ini tidak sepenuhnya berubah sejak awal. Saya menggunakan moment-immutable sampai ini diperbaiki.

Momen @alancnet mungkin tidak akan pernah berubah. Ini terlalu banyak perubahan dan ada cukup dorongan balik dari pengguna yang belajar untuk menerima perilaku saat ini.

Lihat proyek baru mereka: luxon
Ini sangat bagus, modern, tidak dapat diubah(!) dan harus berkinerja jauh lebih baik daripada tidak dapat diubah momen yang hanya membungkus semuanya dalam panggilan .clone() .

Bagi mereka yang ingin beralih dari momentjs ke pendekatan modern, silakan lihat https://github.com/you-dont-need/You-Dont-Need-Momentjs

Sangat terkejut itu bisa berubah!

Seberapa jauh luxon menjadi pengganti? Salah satu alasan saya menggunakan Moment.js adalah dukungan zona waktu - ini adalah suatu keharusan untuk proyek saya.

@alamothe Pertanyaan itu dijawab dengan jelas di situs web: https://moment.github.io/luxon/docs/manual/moment.html

Menutup ini. Seperti yang telah ditunjukkan orang lain, gunakan Luxon jika Anda menginginkan API yang sebagian besar tidak dapat diubah. Terima kasih.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat