Mengapa kita dapat menghapus beberapa properti global objek bawaan?

12

Saya membaca es5 hari ini dan menemukan bahwa atribut [[dapat dikonfigurasi]] di beberapa properti bawaan dari objek global disetel ke true yang berarti kita dapat menghapus properti ini.

Sebagai contoh:

metode join objek Array.prototype memiliki atribut

{[[Writable]]:true, [[Enumerable]]: false, [[Configurable]]: true}

Jadi kita dapat dengan mudah menghapus metode bergabung untuk Array seperti:

delete Array.prototype.join;
alert([1,2,3].join);

Peringatan akan ditampilkan undefineddi chromium 17 saya, firefox 9, yaitu 10, bahkan ie6;

Di Chrome 15 & safari 5.1.1, atribut [[dapat dikonfigurasi]] disetel ke true dan hasil penghapusan juga benar tetapi hasil akhirnya tetap function(){[native code]}. Sepertinya ini adalah bug dan memperbaikinya kromium.

Saya belum melihat itu sebelumnya. Menurut pendapat saya, menghapus fungsi built-in dalam kode pengguna berbahaya, dan akan mengeluarkan banyak bug saat bekerja dengan orang lain. Jadi mengapa ECMAScript membuat keputusan ini?

demix
sumber
Jawaban berganda memuji kemampuan untuk menyesuaikan fungsionalitas bawaan dengan menghapus properti tetapi pendekatan ini hanya diperlukan karena fungsionalitas bawaan pada variabel global alih-alih menggunakan DI. Tampaknya menyesuaikan dengan menghapus properti adalah retas di sekitar desain yang pada dasarnya buruk. Misalnya, jika Anda harus dapat mengubah parser JSON, Anda bisa menulis kode yang mengambil parser JSON sebagai input.
Pasang kembali Monica

Jawaban:

2

Saya cenderung setuju dengan Anda, tetapi di sisi lain saya hanya menemukan situasi di mana saya perlu delete JSON.stringifydalam keadaan tertentu karena bug di Firefox 3.5 . Saya tentu senang dengan kemampuan untuk menambal monyet di sana.

N3dst4
sumber
Mengapa Anda tidak menimpanya saja?
demix
2
Karena hal berikutnya yang terjadi adalah JSON2.js dimuat, yang mendeteksi keberadaan JSON.stringifydan menyuntikkannya jika perlu. Maaf, saya tidak menjelaskan hal itu dalam jawaban saya.
N3dst4
Jadi Anda dapat memodifikasi kode sumber JSON2.js juga, lol
demix
Merupakan ide yang buruk untuk memodifikasi perpustakaan pihak ketiga karena Anda tidak dapat memutakhirkannya tanpa menyalin semua perubahan Anda.
N3dst4
1

Dapat dikonfigurasi bukan tentang penghapusan.

Ini tentang kemampuan untuk mengganti nilai hanya baca.

Ini adalah alat yang sangat kuat, dan nilai-nilai yang tidak dapat dikonfigurasi membuat frustasi jika Anda tidak dapat menghapusnya.

Saya punya beberapa kasus di mana saya perlu memperbaiki bug yang tidak jelas atau menyuntikkan fungsionalitas yang sedikit berbeda (intersepsi, logging). Melakukan itu memerlukan penggantian nilai.

Contoh:

Object.defineProperty(Object.prototype, "foo", {
  value: 42,
  configurable: true
});

var o = {};
o.foo = 50; // fails. foo is not writable
delete Object.prototype.foo;
o.foo = 50; // succeeds
/* optionally put Object.prototype.foo back */

Seluruh ide adalah bahwa jika Anda dapat menghapus properti Anda memiliki lebih banyak kontrol pemrograman meta. Jika Anda tidak bisa menghapusnya maka Anda hanya akan terganggu dengan bahasa tersebut.

Tidak ada alasan bagus untuk membuat properti tidak bisa dihapus selain untuk mengganggu orang.

Raynos
sumber
1
Atribut [[dapat ditulis]] mengontrol kemampuan untuk mengubah nilai. Dalam ES5: [[Tertulis]] Boolean Jika salah, upaya oleh kode ECMAScript untuk mengubah atribut properti [[Nilai]] menggunakan [[Put]] tidak akan berhasil . [[Configurable]] Boolean Jika false, upaya untuk menghapus properti, mengubah properti menjadi properti accessor, atau mengubah atributnya (selain [[Nilai]]) akan gagal.
demix
@ Demix Ya, itu benar ...
Raynos
0

..delete fungsi bawaan dalam kode pengguna berbahaya

Justru sebaliknya. Mengizinkan kustomisasi bagus karena memungkinkan penulis situs web memiliki lebih banyak fleksibilitas.

Jika pembuat situs web perlu memuat kode pihak ke-3 dalam JS VM yang sama dan ingin menggunakan pengurai JS bawaan untuk melakukannya, ia selalu dapat mengamankan properti dengan mengaturnya agar tidak dapat dikonfigurasi sebelum memuat kode pihak ke-3.

Pacerier
sumber