Bagaimana cara membuat namespace di JavaScript sehingga objek dan fungsi saya tidak ditimpa oleh objek dan fungsi lain yang bernama sama? Saya telah menggunakan yang berikut ini:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
Apakah ada cara yang lebih elegan atau ringkas untuk melakukan ini?
javascript
namespaces
javascript-namespaces
Scott McKenzie
sumber
sumber
Jawaban:
Saya suka ini:
sumber
MyApp
, misalnyaMyApp.Views.Profile = {}
daripadaMyApp.users = {}
danMyViews.Profile = {}
. Tidak harus hanya kedalaman dua tingkat saja.Saya menggunakan pendekatan yang ditemukan di situs Enterprise jQuery :
Berikut ini adalah contoh mereka yang menunjukkan cara mendeklarasikan properti dan fungsi pribadi & publik. Semuanya dilakukan sebagai fungsi anonim yang dijalankan sendiri.
Jadi jika Anda ingin mengakses salah satu anggota publik Anda hanya akan pergi
skillet.fry()
atauskillet.ingredients
.Apa yang benar-benar keren adalah bahwa Anda sekarang dapat memperluas namespace menggunakan sintaks yang sama persis.
undefined
Argumen ketigasumber
undefined
argumen ketiga, adalah sumber dari variabel nilaiundefined
. Saat bekerja dengan standar browser / javascript yang lebih lama (ecmascript 5, javascript <1.8.5 ~ firefox 4), variabel lingkup globalundefined
dapat ditulis, sehingga siapa pun dapat menulis ulang nilainya. Menambahkan ketiga, argumen tambahan yang tidak Anda lewati membuatnya bernilaiundefined
, jadi Anda membuat namespace-scopeundefined
yang tidak akan ditulis ulang oleh sumber luar.window.skillet = window.skillet || {}
adalah memungkinkan beberapa skrip ditambahkan dengan aman ke namespace yang sama ketika mereka tidak tahu sebelumnya dalam urutan apa yang akan mereka jalankan. Ini dapat membantu jika Anda ingin dapat menyusun ulang penyertaan skrip Anda secara sewenang-wenang tanpa melanggar kode Anda, atau jika Anda ingin memuat skrip secara asinkron dengan atribut async sehingga tidak memiliki jaminan tentang urutan eksekusi. Lihat stackoverflow.com/questions/6439579/…Cara lain untuk melakukannya, yang saya anggap sedikit kurang membatasi daripada bentuk objek literal, adalah ini:
Di atas cukup seperti pola modul dan apakah Anda suka atau tidak , itu memungkinkan Anda untuk mengekspos semua fungsi Anda sebagai publik, sambil menghindari struktur kaku objek literal.
sumber
ns().publicFunction()
, yaitu ...ns.publicFunction()
berfungsi.new
kata kunci di depanfunction
kata kunci. Pada dasarnya, apa yang dilakukan adalah mendeklarasikan fungsi anonim (dan sebagai fungsi, ia juga merupakan konstruktor), dan kemudian segera memanggilnya sebagai konstruktor menggunakannew
. Dengan demikian, nilai akhir yang disimpan di dalamnyans
adalah instance (unik) dari konstruktor anonim itu. Semoga itu masuk akal.Iya. Sebagai contoh:
maka kamu dapat memiliki
sumber
var your_namespace = your_namespace = your_namespace || {}
Saya biasanya membangunnya sebagai penutup:
Gaya saya selama bertahun-tahun telah mengalami perubahan yang halus sejak menulis ini, dan sekarang saya menemukan diri saya menulis penutupan seperti ini:
Dengan cara ini saya menemukan API publik dan implementasi lebih mudah dimengerti. Pikirkan pernyataan kembali sebagai antarmuka publik untuk implementasi.
sumber
MYNS.subns = MYNS.subns || {}
??var foo = function
danfunction foo
serupa, bersifat pribadi; karena sifat JavaScript yang diketik secara dinamis, yang terakhir ini sedikit lebih cepat karena melompati beberapa instruksi di sebagian besar saluran pipa juru bahasa. Denganvar foo
, sistem jenis harus dipanggil untuk mencari tahu jenis apa yang ditugaskan untuk kata var, sementara denganfunction foo
, sistem jenis secara otomatis tahu itu adalah fungsi, jadi beberapa panggilan fungsi dilewati, yang diterjemahkan menjadi lebih sedikit permintaan instruksi CPU sepertijmp
,pushq
,popq
, dll, yang diterjemahkan ke pipa CPU lebih pendek.function foo
sintaks lebih mudah dibaca. Dan saya masih suka versi saya.Karena Anda dapat menulis file JavaScript yang berbeda dan kemudian menggabungkan atau tidak menggabungkannya dalam aplikasi, masing-masing harus dapat memulihkan atau membangun objek namespace tanpa merusak karya file lain ...
Satu file mungkin bermaksud menggunakan namespace
namespace.namespace1
:File lain mungkin ingin menggunakan namespace
namespace.namespace2
:Kedua file ini dapat hidup bersama atau terpisah tanpa bertabrakan.
sumber
Inilah cara Stoyan Stefanov melakukannya di buku Pola Javascript yang menurut saya sangat bagus (ini juga menunjukkan bagaimana ia melakukan komentar yang memungkinkan dokumentasi API yang dibuat secara otomatis, dan cara menambahkan metode ke prototipe objek khusus):
sumber
Saya menggunakan pendekatan ini:
Kode eksternal dapat berupa:
sumber
ns = ns || {}
mungkin tampak lebih defensif, itu dapat menyebabkan hasil yang tidak terduga lainnya.Ini adalah tindak lanjut dari tautan user106826 ke Namespace.js. Sepertinya proyek pindah ke GitHub . Sekarang smith / namespacedotjs .
Saya telah menggunakan bantuan JavaScript sederhana ini untuk proyek kecil saya dan sejauh ini tampaknya ringan namun cukup fleksibel untuk menangani namespacing dan memuat modul / kelas. Akan lebih bagus jika itu akan memungkinkan saya untuk mengimpor paket ke namespace pilihan saya, bukan hanya namespace global ... huh, tapi itu intinya.
Ini memungkinkan Anda untuk mendeklarasikan namespace kemudian mendefinisikan objek / modul di namespace itu:
Pilihan lain adalah mendeklarasikan namespace dan isinya sekaligus:
Untuk contoh penggunaan lainnya, lihat file example.js di sumber .
sumber
Sampel:
Anda dapat mendeklarasikan
local
variabelsame
,, suka,self
dan tetapkan secara opsionallocal.onTimeout
jika Anda ingin itu bersifat pribadi.sumber
Anda dapat mendeklarasikan fungsi sederhana untuk menyediakan ruang nama.
sumber
Jika Anda membutuhkan ruang lingkup pribadi:
lain jika Anda tidak akan pernah menggunakan ruang lingkup pribadi:
sumber
Pola Modul awalnya didefinisikan sebagai cara untuk menyediakan enkapsulasi pribadi dan publik untuk kelas dalam rekayasa perangkat lunak konvensional.
Ketika bekerja dengan pola Module, kita mungkin menemukan manfaat untuk mendefinisikan template sederhana yang kita gunakan untuk memulainya. Berikut ini salah satu yang mencakup spasi nama, variabel publik dan pribadi.
Dalam JavaScript, pola Module digunakan untuk lebih meniru konsep kelas sedemikian rupa sehingga kami dapat memasukkan metode publik / pribadi dan variabel di dalam objek tunggal, sehingga melindungi bagian-bagian tertentu dari lingkup global. Hasilnya adalah pengurangan kemungkinan nama fungsi kami bertentangan dengan fungsi lain yang didefinisikan dalam skrip tambahan pada halaman.
Keuntungan
mengapa pola Modul merupakan pilihan yang baik? Sebagai permulaan, ini jauh lebih bersih bagi pengembang yang datang dari latar belakang berorientasi objek daripada gagasan enkapsulasi sejati, setidaknya dari perspektif JavaScript.
Kedua, ini mendukung data pribadi - jadi, dalam pola Modul, bagian publik dari kode kami dapat menyentuh bagian pribadi, namun dunia luar tidak dapat menyentuh bagian pribadi kelas.
Kekurangan
Kerugian dari pola Modul adalah ketika kita mengakses anggota publik dan swasta secara berbeda, ketika kita ingin mengubah visibilitas, kita sebenarnya harus membuat perubahan di setiap tempat anggota itu digunakan.
Kami juga tidak dapat mengakses anggota pribadi dalam metode yang ditambahkan ke objek di kemudian hari . Yang mengatakan, dalam banyak kasus, pola Modul masih cukup berguna dan ketika digunakan dengan benar, tentu memiliki potensi untuk meningkatkan struktur aplikasi kita.
Pola Penyingkapan Modul
Sekarang kita sedikit lebih terbiasa dengan pola modul, mari kita lihat versi yang sedikit lebih baik - pola Revealing Module milik Christian Heilmann.
Pola Revealing Module muncul ketika Heilmann frustrasi dengan fakta bahwa ia harus mengulangi nama objek utama ketika kami ingin memanggil satu metode publik dari yang lain atau mengakses variabel publik. Ia juga tidak menyukai persyaratan pola Modul karena harus beralih untuk menolak notasi literal untuk hal-hal yang ingin dipublikasikan.
Hasil dari usahanya adalah pola yang diperbarui di mana kami hanya akan mendefinisikan semua fungsi dan variabel kami dalam lingkup pribadi dan mengembalikan objek anonim dengan petunjuk ke fungsi pribadi yang ingin kami ungkapkan sebagai publik.
Contoh cara menggunakan pola Modul Penyingkapan dapat ditemukan di bawah
Keuntungan
Pola ini memungkinkan sintaks skrip kami menjadi lebih konsisten. Itu juga membuatnya lebih jelas di akhir modul mana dari fungsi dan variabel kita dapat diakses secara publik yang memudahkan keterbacaan.
Kekurangan
Kerugian dari pola ini adalah bahwa jika fungsi privat mengacu pada fungsi publik, fungsi publik itu tidak dapat diganti jika tambalan diperlukan. Ini karena fungsi privat akan terus merujuk pada implementasi privat dan polanya tidak berlaku untuk anggota publik, hanya untuk fungsi.
Anggota objek publik yang merujuk ke variabel pribadi juga tunduk pada catatan aturan no-patch di atas.
sumber
Saya membuat namespace yang terinspirasi oleh modul Erlang. Ini adalah pendekatan yang sangat fungsional, tapi itulah cara saya menulis kode JavaScript saya hari ini.
Ini memberikan penutupan namespace global dan mengekspos fungsi set yang didefinisikan dalam penutupan itu.
sumber
Setelah porting beberapa perpustakaan saya ke proyek yang berbeda, dan harus terus-menerus mengubah tingkat atas (nama statis) namespace, saya telah beralih menggunakan fungsi pembantu kecil (open source) untuk mendefinisikan ruang nama.
Deskripsi manfaat ada di posting blog saya . Anda dapat mengambil kode sumber di sini .
Salah satu manfaat yang sangat saya sukai adalah isolasi antar modul sehubungan dengan urutan pemuatan. Anda dapat merujuk ke modul eksternal SEBELUM itu dimuat. Dan referensi objek yang Anda dapatkan akan diisi ketika kode tersedia.
sumber
Saya menggunakan sintaks berikut untuk namespace.
jsfiddle: http://jsfiddle.net/rpaul/4dngxwb3/1/
sumber
Saya terlambat 7 tahun ke pesta, tetapi melakukan sedikit pekerjaan sekitar 8 tahun yang lalu:
Penting untuk dapat dengan mudah dan efisien membuat beberapa ruang nama bersarang untuk menjaga aplikasi web yang kompleks terorganisir dan dikelola, sambil menghormati JavaScript namespace global (mencegah pencemaran namespace), dan dengan tidak mengalahkan benda apa pun yang ada di jalur namespace saat melakukan hal itu .
Dari penjelasan di atas, ini adalah solusi saya sekitar tahun 2008:
Ini bukan menciptakan namespace, tetapi menyediakan fungsi untuk membuat namespace.
Ini dapat diringkas ke liner satu minified:
Contoh penggunaan:
Atau, sebagai satu pernyataan:
Keduanya kemudian dieksekusi sebagai:
Jika Anda tidak memerlukan dukungan untuk browser lawas, versi yang diperbarui:
Sekarang, saya akan ragu mengekspos
namespace
ke namespace global itu sendiri. (Sayang sekali bahasa dasar tidak menyediakan ini untuk kami!) Jadi saya biasanya menggunakan ini sendiri sebagai penutup, seperti:Dalam aplikasi yang lebih besar, ini hanya perlu didefinisikan sekali pada awal pemuatan halaman (untuk aplikasi web berbasis klien). File tambahan kemudian dapat menggunakan kembali fungsi namespace jika disimpan (disertakan sebagai "opsional" di atas). Paling buruk, jika fungsi ini dinyatakan ulang beberapa kali - itu hanya beberapa baris kode, dan lebih sedikit jika diperkecil.
sumber
Saya pikir Anda semua menggunakan terlalu banyak kode untuk masalah sederhana. Tidak perlu membuat repo untuk itu. Inilah fungsi garis tunggal.
Cobalah :
sumber
Saya suka solusi Jaco Pretorius, tetapi saya ingin membuat kata kunci "ini" sedikit lebih berguna dengan mengarahkannya ke objek module / namespace. Versi wajan saya:
sumber
Pola favorit saya menjadi belakangan ini:
Tentu saja, return bisa di bagian akhir, tetapi jika hanya deklarasi fungsi yang mengikutinya, akan lebih mudah untuk melihat apa itu namespace, dan apa yang diekspos API.
Pola penggunaan ekspresi fungsi dalam kasus-kasus seperti itu mengakibatkan tidak dapat mengetahui metode apa yang terbuka tanpa membahas seluruh kode.
sumber
namespace.a();
Jika menggunakan Makefile Anda dapat melakukan ini.
Saya lebih suka menggunakan Makefile setelah saya mendapatkan sekitar 1000 baris karena saya dapat secara efektif mengomentari sejumlah besar kode dengan menghapus satu baris di makefile. Itu membuatnya mudah untuk mengutak-atik barang. Juga, dengan teknik ini namespace hanya muncul sekali di awal sehingga mudah untuk diubah dan Anda tidak harus terus mengulanginya di dalam kode perpustakaan.
Skrip shell untuk pengembangan langsung di browser saat menggunakan makefile:
Tambahkan ini sebagai tugas make 'go' dan Anda bisa 'make go' untuk menjaga build Anda diperbarui saat Anda membuat kode.
sumber
Cukup tindak lanjut dari jawaban Ionuț G. Stan, tetapi menunjukkan manfaat dari kode yang tidak berantakan dengan menggunakan
var ClassFirst = this.ClassFirst = function() {...}
, yang mengambil keuntungan dari pelingkupan penutupan JavaScript untuk mengurangi keruwetan namespace untuk kelas di namespace yang sama.Keluaran:
sumber
Saya telah menulis perpustakaan namespacing lain yang bekerja sedikit lebih seperti paket / unit lakukan dalam bahasa lain. Ini memungkinkan Anda untuk membuat paket kode JavaScript dan referensi paket itu dari kode lain:
File hello.js
File Example.js
Hanya file kedua yang perlu dimasukkan dalam halaman. Ketergantungannya (file hello.js dalam contoh ini) akan secara otomatis dimuat dan objek yang diekspor dari dependensi tersebut akan digunakan untuk mengisi argumen fungsi panggilan balik.
Anda dapat menemukan proyek terkait di Paket JS .
sumber
Kita dapat menggunakannya secara mandiri dengan cara ini:
sumber
Kebiasaan saya adalah menggunakan fungsi myName () sebagai penyimpanan properti, dan kemudian var myName sebagai pemegang "metode" ...
Apakah ini cukup sah atau tidak, pukul saya! Saya mengandalkan logika PHP saya sepanjang waktu, dan semuanya berjalan dengan baik. : D
if (this !== that) myObj.fName1(); else myObj.fName2();
Referensi untuk ini: JavaScript: Membuat Objek dengan Object.create ()
sumber
Dalam JavaScript tidak ada metode yang telah ditentukan untuk menggunakan ruang nama. Dalam JavaScript kita harus membuat metode sendiri untuk mendefinisikan NameSpaces. Berikut adalah prosedur yang kami ikuti dalam teknologi Oodles.
Mendaftarkan NameSpace Berikut adalah fungsi untuk mendaftarkan ruang nama
Untuk mendaftarkan Namespace, panggil fungsi di atas dengan argumen sebagai ruang nama yang dipisahkan oleh
'.'
(titik). Sebagai Contoh Biarkan nama aplikasi Anda adalah jumlah besar sekali. Anda dapat membuat namespace dengan metode berikutPada dasarnya itu akan membuat struktur NameSpaces Anda seperti di bawah ini di backend:
Dalam fungsi di atas Anda telah mendaftarkan namespace yang dipanggil
"oodles.HomeUtilities"
dan"oodles.GlobalUtilities"
. Untuk memanggil ruang nama ini kami membuat variabel yaitu var$OHU
dan var$OGU
.Variabel-variabel ini tidak lain adalah alias untuk Menginternalisasi namespace. Sekarang, Setiap kali Anda mendeklarasikan fungsi milik
HomeUtilities
Anda, akan mendeklarasikannya seperti berikut:Di atas adalah inisialisasi nama fungsi dan dimasukkan ke dalam namespace
$OHU
. dan untuk memanggil fungsi ini di mana saja dalam file skrip. Cukup gunakan kode berikut.Demikian pula dengan NameSpaces yang lain.
Semoga ini bisa membantu.
sumber
JavaScript tidak mendukung namespace secara default. Jadi jika Anda membuat elemen apa pun (fungsi, metode, objek, variabel) maka itu menjadi global dan mencemari namespace global. Mari kita ambil contoh mendefinisikan dua fungsi tanpa namespace,
Itu selalu memanggil definisi fungsi kedua. Dalam hal ini, namespace akan menyelesaikan masalah nama tabrakan.
sumber