UPDATE 2015:
Seperti yang ditunjukkan oleh jawaban ke - 7 , sekarang ES6 (ECMAScript 2015) telah diselesaikan, dokumentasi yang lebih sesuai sekarang tersedia:
Jawaban asli (untuk pemahaman (historis) dan contoh tambahan) :
The Reflection proposal
tampaknya telah berkembang ke Draft ECMAScript 6 Keterangan . Dokumen ini saat ini menguraikan metode Reflect
-object dan hanya menyatakan hal berikut tentangReflect
-object itu sendiri:
Objek Reflect adalah satu objek biasa.
Nilai slot internal [[Prototipe]] dari objek Reflect adalah objek prototipe Objek bawaan standar (19.1.3).
Objek Reflect bukanlah objek fungsi. Itu tidak memiliki metode internal [[Membangun]]; tidak mungkin menggunakan objek Reflect sebagai konstruktor dengan yang baru operator . Objek Reflect juga tidak memiliki metode internal [[Call]]; tidak mungkin untuk memanggil objek Reflect sebagai sebuah fungsi.
Namun demikian, ada penjelasan singkat tentang kegunaannya dalam ES Harmony :
Modul "@reflect" memiliki beberapa tujuan:
- Sekarang kita memiliki modul, modul "@reflect" adalah tempat yang lebih alami untuk banyak metode refleksi yang sebelumnya didefinisikan pada Object. Untuk tujuan kompatibilitas mundur, kecil kemungkinan metode statis pada Object akan menghilang. Namun, metode baru mungkin harus ditambahkan ke modul "@reflect" daripada ke konstruktor Object.
- Tempat alami untuk proxy, menghindari kebutuhan pengikatan Proxy global.
- Sebagian besar metode dalam modul ini memetakan satu-ke-satu ke dalam perangkap Proxy. Penangan proxy memerlukan metode ini untuk meneruskan operasi dengan mudah, seperti yang ditunjukkan di bawah ini.
Sehingga Reflect
objek tersebut menyediakan sejumlah fungsi utilitas, banyak di antaranya tampak tumpang tindih dengan metode ES5 yang ditentukan pada Objek global.
Namun, itu tidak benar-benar menjelaskan masalah apa yang ingin diselesaikan atau fungsionalitas apa yang ditambahkan. Saya curiga ini bisa digoyahkan dan memang, spesifikasi harmoni di atas terkait dengan 'non-normatif, perkiraan penerapan metode ini' .
Memeriksa kode itu dapat memberikan gagasan (lebih lanjut) tentang penggunaannya, tetapi untungnya ada juga wiki yang menguraikan sejumlah alasan mengapa objek Reflect berguna :
(Saya telah menyalin (dan memformat) teks berikut untuk referensi di masa mendatang dari itu sumber karena mereka adalah satu - satunya contoh yang dapat saya temukan. Selain itu, mereka masuk akal, sudah memiliki penjelasan yang baik dan menyentuh contoh pertanyaan apply
.)
Nilai kembali yang lebih berguna
Banyak operasi dalam Reflect
mirip dengan operasi ES5 yang ditentukan pada Object
, seperti Reflect.getOwnPropertyDescriptor
dan Reflect.defineProperty
. Namun, sedangkan Object.defineProperty(obj, name, desc)
akan kembali obj
ketika properti berhasil didefinisikan, atau melempar TypeError
sebaliknya, Reflect.defineProperty(obj, name, desc)
ditentukan untuk mengembalikan boolean yang menunjukkan apakah properti berhasil didefinisikan atau tidak. Ini memungkinkan Anda untuk memfaktorkan ulang kode ini:
try {
Object.defineProperty(obj, name, desc);
} catch (e) {
}
Untuk ini:
if (Reflect.defineProperty(obj, name, desc)) {
} else {
}
Metode lain yang mengembalikan status sukses boolean adalah Reflect.set
(untuk memperbarui properti), Reflect.deleteProperty
(untuk menghapus properti), Reflect.preventExtensions
(untuk membuat objek tidak dapat diperluas) dan Reflect.setPrototypeOf
(untuk memperbarui tautan prototipe objek).
Operasi kelas satu
Di ES5, cara untuk mendeteksi apakah suatu objek obj
mendefinisikan atau mewarisi nama properti tertentu adalah dengan menulis (name in obj)
. Demikian pula untuk menghapus properti, seseorang menggunakan delete obj[name]
. Meskipun sintaks khusus bagus dan pendek, itu juga berarti Anda harus secara eksplisit menggabungkan operasi ini dalam fungsi ketika Anda ingin meneruskan operasi sebagai nilai kelas satu.
Dengan Reflect
, operasi ini dengan mudah didefinisikan sebagai fungsi kelas satu:
Reflect.has(obj, name)
adalah setara fungsional (name in obj)
dan Reflect.deleteProperty(obj, name)
merupakan fungsi yang melakukan hal yang sama sepertidelete obj[name].
Aplikasi fungsi yang lebih andal
Di ES5, ketika seseorang ingin memanggil fungsi f
dengan sejumlah variabel argumen yang dikemas sebagai array args
dan mengikat this
nilainya obj
, seseorang dapat menulis:
f.apply(obj, args)
Namun, f
bisa jadi sebuah objek yang dengan sengaja atau tidak sengaja mendefinisikan apply
metodenya sendiri . Saat Anda benar-benar ingin memastikan bahwa fungsi built-in apply
dipanggil, seseorang biasanya menulis:
Function.prototype.apply.call(f, obj, args)
Tidak hanya bertele-tele ini, dengan cepat menjadi sulit untuk dipahami. Dengan Reflect
, sekarang Anda dapat melakukan panggilan fungsi yang andal dengan cara yang lebih singkat dan lebih mudah dipahami:
Reflect.apply(f, obj, args)
Konstruktor argumen-variabel
Bayangkan Anda ingin memanggil fungsi konstruktor dengan sejumlah variabel argumen. Di ES6, berkat sintaks penyebaran baru, dimungkinkan untuk menulis kode seperti:
var obj = new F(...args)
Di ES5, ini lebih sulit untuk ditulis, karena seseorang hanya dapat menggunakan F.apply
atau F.call
memanggil fungsi dengan sejumlah variabel argumen, tetapi tidak ada F.construct
fungsi ke new
fungsi dengan sejumlah variabel argumen. Dengan Reflect
, sekarang seseorang dapat menulis, di ES5:
var obj = Reflect.construct(F, args)
Perilaku penerusan default untuk Perangkap proxy
Saat menggunakan Proxy
objek untuk membungkus objek yang sudah ada, sangat umum untuk mencegat operasi, melakukan sesuatu, dan kemudian "melakukan hal default", yang biasanya menerapkan operasi yang dicegat ke objek yang dibungkus. Misalnya, saya ingin mencatat semua akses properti ke suatu objek obj
:
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
}
});
The Reflect
dan Proxy
API dirancang bersama-sama , sehingga untuk setiap Proxy
perangkap, ada sebuah metode yang sesuai pada Reflect
yang "melakukan hal yang default". Karenanya, setiap kali Anda merasa ingin "melakukan default" di dalam penangan Proxy, hal yang benar untuk dilakukan adalah selalu memanggil metode yang sesuai dalam Reflect
objek:
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
return Reflect.get(target, name);
}
});
Jenis pengembalian Reflect
metode dijamin kompatibel dengan jenis pengembalian Proxy
perangkap.
Kontrol pengikatan pengakses ini
Di ES5, cukup mudah untuk melakukan akses properti umum atau pembaruan properti. Misalnya:
var name = ...
obj[name]
obj[name] = value
Metode Reflect.get
dan Reflect.set
memungkinkan Anda melakukan hal yang sama, tetapi sebagai tambahan menerima sebagai argumen opsional terakhir sebuah receiver
parameter yang memungkinkan Anda menyetel secara eksplisit this
-binding ketika properti yang Anda dapatkan / setel adalah pengakses:
var name = ...
Reflect.get(obj, name, wrapper)
Reflect.set(obj, name, value, wrapper)
Ini kadang-kadang berguna saat Anda membungkus obj
dan Anda ingin pengiriman otomatis apa pun di dalam pengakses dirutekan ulang ke pembungkus Anda, misalnya jika obj
didefinisikan sebagai:
var obj = {
get foo() { return this.bar(); },
bar: function() { ... }
}
Menelepon Reflect.get(obj, "foo", wrapper)
akan menyebabkan this.bar()
panggilan dialihkan ke wrapper
.
Hindari warisan __proto__
Pada beberapa browser, __proto__
didefinisikan sebagai properti khusus yang memberikan akses ke prototipe objek. ES5 menstandarkan metode baru Object.getPrototypeOf(obj)
untuk menanyakan prototipe. Reflect.getPrototypeOf(obj)
tidak persis sama, kecuali itu Reflect
juga mendefinisikan yang sesuai Reflect.setPrototypeOf(obj, newProto)
untuk menyetel prototipe objek. Ini adalah cara baru yang sesuai dengan ES6 untuk memperbarui prototipe objek.
Perhatikan bahwa: setPrototypeOf
juga ada diObject
(sebagai benar ditunjukkan oleh KNU 's komentar )!
EDIT:
Catatan samping (menangani komentar ke Q): Ada jawaban singkat dan sederhana di 'Q: ES6 Modules vs HTML Imports' yang menjelaskan Realms
dan Loader
objek.
Penjelasan lain ditawarkan oleh tautan ini :
Objek realm mengabstraksikan gagasan lingkungan global yang berbeda, dengan objek globalnya sendiri, salinan pustaka standar, dan "intrinsik" (objek standar yang tidak terikat ke variabel global, seperti nilai awal Object.prototype).
Web yang dapat diperluas : Ini adalah padanan dinamis dari sumber yang sama
<iframe>
tanpa DOM.
Layak disebutkan: semua ini masih dalam konsep, ini bukan spesifikasi yang terukir di batu! Ini ES6, jadi ingatlah kompatibilitas browser!
Semoga ini membantu!
Reflect
hanyalah wadah untukRealm
danLoader
objek, tetapi saya juga tidak tahu apa yang dilakukan oleh objek.