Bagaimana saya bisa membuat variabel statis di Javascript?
javascript
variables
static
closures
Rajat
sumber
sumber
someFunc = () => { MyClass.myStaticVariable = 1; }
. Kemudian cukup buat metode statis untuk mengembalikan anggota statis, misstatic getStatic() { return MyClass.myStaticVariable; }
. Maka Anda bisa meneleponMyClass.getStatic()
dari luar kelas untuk mendapatkan data statis!Jawaban:
Jika Anda berasal dari bahasa berorientasi objek berbasis kelas, diketik secara statis (seperti Java, C ++ atau C #) Saya berasumsi bahwa Anda mencoba untuk membuat variabel atau metode yang terkait dengan "tipe" tetapi tidak ke sebuah instance.
Contoh menggunakan pendekatan "klasik", dengan fungsi konstruktor mungkin dapat membantu Anda menangkap konsep JavaScript OO dasar:
staticProperty
didefinisikan dalam objek MyClass (yang merupakan fungsi) dan tidak ada hubungannya dengan instance yang dibuat, JavaScript memperlakukan fungsi sebagai objek kelas satu , jadi sebagai objek, Anda dapat menetapkan properti ke fungsi.UPDATE: ES6 memperkenalkan kemampuan untuk mendeklarasikan kelas melalui
class
kata kunci. Ini adalah gula sintaks atas warisan berbasis prototipe yang ada.Kata
static
kunci memungkinkan Anda untuk dengan mudah mendefinisikan properti atau metode statis di kelas.Mari kita lihat contoh di atas diimplementasikan dengan kelas ES6:
sumber
privilegedMethod
tidak setara dengan metode pribadi di OO karena sepertinya itu bisa dipanggil pada instance dari MyClass? Apakah maksud Anda ini istimewa karena dapat mengaksesprivateVariable
?this.constructor
dapat digunakan untuk mengakses variabel statis dari "metode instance"? Jika ya, ada baiknya menambahkannya ke jawaban.MyClass.prototype.staticProperty = "baz";
atau bahkan lebih benar dengan prinsip-prinsip OO properti statis sebenarnya harus didefinisikan sebagai fungsi anonimMyClass.prototype.staticProperty = function () {return staticVar;}
dan sehingga semua instance mengakses variabel tunggal yang juga dapat diubah dengan setter.Anda mungkin mengambil keuntungan dari fakta bahwa fungsi JS juga objek - yang berarti mereka dapat memiliki properti.
Misalnya, dengan mengutip contoh yang diberikan pada variabel Statis artikel (sekarang lenyap) dalam Javascript :
Jika Anda memanggil fungsi itu beberapa kali, Anda akan melihat penghitung bertambah.
Dan ini mungkin solusi yang jauh lebih baik daripada mencemari namespace global dengan variabel global.
Dan berikut ini adalah solusi yang mungkin, berdasarkan penutupan: Trik menggunakan variabel statis dalam javascript :
Yang memberi Anda hasil yang sama - kecuali, kali ini, nilai yang bertambah dikembalikan, alih-alih ditampilkan.
sumber
countMyself.counter = countMyself.counter || initial_value;
jika variabel statis tidak akan pernah menjadi falsey (false, 0, null, atau string kosong)===
untuktypeof
cek lain, Anda akan mendapatkan paksaan aneh.Anda melakukannya melalui IIFE (ekspresi fungsi yang langsung dipanggil):
sumber
Anda dapat menggunakan arguments.callee untuk menyimpan variabel "statis" (ini juga berguna dalam fungsi anonim):
sumber
arguments.callee
sudah ditinggalkan.callee
sepertinya hal yang baik untuk dimiliki. Saya bertanya-tanya mengapa peretasan membuat mereka memutuskan untuk mencabut ini ...: |Saya telah melihat beberapa jawaban yang serupa, tetapi saya ingin menyebutkan bahwa posting ini paling menggambarkannya, jadi saya ingin membagikannya dengan Anda.
Inilah beberapa kode yang diambil darinya, yang telah saya modifikasi untuk mendapatkan contoh lengkap yang semoga bermanfaat bagi komunitas karena dapat digunakan sebagai templat desain untuk kelas.
Itu juga menjawab pertanyaan Anda:
Dengan contoh itu, Anda dapat mengakses properti / fungsi statis sebagai berikut:
Dan objek properti / fungsi cukup sebagai:
Perhatikan bahwa di podcast.immutableProp (), kami memiliki penutup : Referensi ke _somePrivateVariable disimpan di dalam fungsi.
Anda bahkan dapat mendefinisikan getter dan setter . Lihatlah potongan kode ini (di mana
d
prototipe objek yang ingin Anda deklarasikan properti,y
adalah variabel pribadi yang tidak terlihat di luar konstruktor):Ini mendefinisikan properti
d.year
viaget
danset
fungsinya - jika Anda tidak menentukanset
, maka properti tersebut hanya baca dan tidak dapat dimodifikasi (perlu diketahui bahwa Anda tidak akan mendapatkan kesalahan jika Anda mencoba mengaturnya, tetapi tidak berpengaruh). Setiap properti memiliki atributwritable
,configurable
(diizinkan untuk mengubah setelah deklarasi) danenumerable
(memungkinkan untuk menggunakannya sebagai enumerator), yang sesuai standarfalse
. Anda dapat mengaturnya melaluidefineProperty
parameter ke-3, misenumerable: true
.Yang juga valid adalah sintaks ini:
yang mendefinisikan properti yang dapat dibaca / ditulis
a
, properti hanya-bacab
dan properti hanya-tulisc
, di mana propertia
dapat diakses.Pemakaian:
Catatan:
Untuk menghindari perilaku tak terduga jika Anda lupa
new
kata kunci, saya sarankan Anda menambahkan fungsi berikutPodcast
:Sekarang kedua instantiasi berikut akan berfungsi seperti yang diharapkan:
Pernyataan 'baru' membuat objek baru dan menyalin semua properti dan metode, yaitu
Perhatikan juga, bahwa dalam beberapa situasi akan berguna untuk menggunakan
return
pernyataan dalam fungsi konstruktorPodcast
untuk mengembalikan fungsi kustom objek yang dilindungi kelas secara internal tetapi bergantung pada yang perlu diekspos. Ini dijelaskan lebih lanjut dalam bab 2 (Objek) dari seri artikel.Anda bisa mengatakan itu
a
danb
mewarisi dariPodcast
. Sekarang, bagaimana jika Anda ingin menambahkan metode ke Podcast yang berlaku untuk semuanya setelaha
danb
telah di-instanciated? Dalam hal ini, gunakan yang.prototype
berikut ini:Sekarang telepon
a
danb
lagi:Anda dapat menemukan detail lebih lanjut tentang prototipe di sini . Jika Anda ingin melakukan lebih banyak warisan, saya sarankan melihat ke dalam ini .
Seri artikel yang saya sebutkan di atas sangat disarankan untuk dibaca, termasuk juga topik-topik berikut:
Perhatikan bahwa penyisipan titik koma otomatis "fitur" dari JavaScript (sebagaimana disebutkan dalam 6.) seringkali bertanggung jawab untuk menyebabkan masalah aneh pada kode Anda. Oleh karena itu, saya lebih suka menganggapnya sebagai bug daripada sebagai fitur.
Jika Anda ingin membaca lebih lanjut, berikut ini adalah artikel MSDN yang cukup menarik tentang topik-topik ini, beberapa di antaranya dijelaskan di sana memberikan lebih banyak detail.
Yang juga menarik untuk dibaca (juga mencakup topik-topik yang disebutkan di atas) adalah artikel-artikel dari MDN JavaScript Guide :
Jika Anda ingin tahu cara meniru
out
parameter c # (seperti dalamDateTime.TryParse(str, out result)
) dalam JavaScript, Anda dapat menemukan kode sampel di sini.Anda yang bekerja dengan IE (yang tidak memiliki konsol untuk JavaScript kecuali Anda membuka alat pengembang menggunakan F12dan membuka tab konsol) mungkin menemukan potongan berikut ini bermanfaat. Ini memungkinkan Anda untuk menggunakan
console.log(msg);
sebagaimana digunakan dalam contoh di atas. Cukup masukkan sebelumPodcast
fungsi.Untuk kenyamanan Anda, inilah kode di atas dalam satu cuplikan kode tunggal lengkap:
Tampilkan cuplikan kode
Catatan:
Beberapa tips, petunjuk, dan rekomendasi yang bagus tentang pemrograman JavaScript secara umum dapat Anda temukan di sini (praktik terbaik JavaScript) dan di sana ('var' versus 'let') . Juga disarankan artikel ini tentang typecasts implisit (pemaksaan) .
Cara mudah untuk menggunakan kelas dan mengompilasinya ke dalam JavaScript adalah TypeScript. Berikut adalah taman bermain di mana Anda dapat menemukan beberapa contoh yang menunjukkan kepada Anda cara kerjanya. Bahkan jika Anda tidak menggunakan TypeScript saat ini, Anda dapat melihatnya karena Anda dapat membandingkan TypeScript dengan hasil JavaScript pada tampilan berdampingan. Sebagian besar contoh sederhana, tetapi ada juga contoh Raytracer yang dapat Anda coba secara instan. Saya sarankan terutama melihat contoh "Menggunakan Kelas", "Menggunakan Warisan" dan "Menggunakan Generik" dengan memilihnya di kotak kombo - ini adalah templat yang bagus yang dapat langsung Anda gunakan dalam JavaScript. Naskah digunakan dengan Angular.
Untuk mencapai enkapsulasi variabel lokal, fungsi dll dalam JavaScript, saya sarankan untuk menggunakan pola seperti berikut (JQuery menggunakan teknik yang sama):
Tentu saja, Anda dapat - dan harus - memasukkan kode skrip ke dalam
*.js
file terpisah ; ini hanya ditulis sebaris untuk menjaga contoh singkat.Fungsi self-invocing (juga dikenal sebagai IIFE = Ekspresi Fungsi Segera Diminta) dijelaskan lebih rinci di sini .
sumber
sumber
Jawaban yang diperbarui:
Di ECMAScript 6 , Anda dapat membuat fungsi statis menggunakan
static
kata kunci:Kelas ES6 tidak memperkenalkan semantik baru untuk statika. Anda dapat melakukan hal yang sama di ES5 seperti ini:
Anda dapat menetapkan ke properti
Foo
karena dalam fungsi JavaScript adalah objek.sumber
Foo.bar;
mengembalikan fungsi yang ditugaskan padanya, bukan string yang dikembalikan oleh fungsi seperti komentar Anda.bar
propertiFoo
menjadi3
seperti ini:Foo.bar = 3;
Contoh dan penjelasan berikut berasal dari buku Professional JavaScript for Web Developers 2nd Edition karya Nicholas Zakas. Ini adalah jawaban yang saya cari jadi saya pikir akan sangat membantu untuk menambahkannya di sini.
The
Person
konstruktor dalam contoh ini memiliki akses ke nama variabel pribadi, seperti melakukangetName()
dansetName()
metode. Dengan menggunakan pola ini, variabel nama menjadi statis dan akan digunakan di antara semua instance. Ini berarti memanggilsetName()
satu instance mempengaruhi semua instance lainnya. MemanggilsetName()
atau membuatPerson
instance baru akan menetapkan variabel nama ke nilai baru. Ini menyebabkan semua instance mengembalikan nilai yang sama.sumber
Jika Anda menggunakan sintaks kelas baru maka Anda sekarang dapat melakukan hal berikut:
Ini secara efektif membuat variabel statis dalam JavaScript.
sumber
MyClass
definisi di luar konstruksi kelas.Jika Anda ingin mendeklarasikan variabel statis untuk membuat konstanta dalam aplikasi Anda maka saya menemukan berikut ini sebagai pendekatan yang paling sederhana
sumber
Tentang
class
diperkenalkan oleh ECMAScript 2015. Jawaban lainnya tidak sepenuhnya jelas.Berikut adalah contoh yang menunjukkan cara membuat var statis
staticVar
denganClassName
.var
sintaks:Untuk mengakses variabel statis, kami menggunakan
.constructor
properti yang mengembalikan referensi ke fungsi konstruktor objek yang membuat kelas. Kita dapat menyebutnya di dua instance yang dibuat:sumber
Ada jawaban serupa lainnya, tetapi tidak ada yang cukup menarik bagi saya. Inilah yang akhirnya saya dapatkan:
sumber
Selain yang lain, saat ini ada rancangan ( proposal tahap-2 ) tentang Proposal ECMA yang memperkenalkan bidang
static
publik di kelas. ( bidang pribadi dipertimbangkan )Menggunakan contoh dari proposal,
static
sintaks yang diusulkan akan terlihat seperti ini:dan setara dengan yang berikut yang telah disorot orang lain:
Anda kemudian dapat mengaksesnya melalui
CustomDate.epoch
.Anda dapat melacak proposal baru di
proposal-static-class-features
.Saat ini, babel mendukung fitur ini dengan plugin transformasi properti kelas yang dapat Anda gunakan. Selain itu, meskipun masih dalam proses,
V8
sedang mengimplementasikannya .sumber
Anda dapat membuat variabel statis dalam JavaScript seperti di bawah ini. Ini
count
adalah variabel statis.Anda dapat menetapkan nilai ke variabel statis menggunakan
Person
fungsi, atau salah satu dari instance:sumber
Jika Anda ingin membuat variabel statis global:
Ganti variabel dengan yang di bawah ini:
sumber
Hal terdekat dalam JavaScript ke variabel statis adalah variabel global - ini hanyalah variabel yang dideklarasikan di luar lingkup fungsi atau objek literal:
Hal lain yang bisa Anda lakukan adalah menyimpan variabel global di dalam objek literal seperti ini:
Dan kemudian mengakses Variabel seperti ini:
foo.bar
.sumber
Untuk menyingkat semua konsep kelas di sini, uji ini:
Nah, cara lain untuk melihat praktik terbaik dalam hal ini, adalah dengan melihat bagaimana coffeescript menerjemahkan konsep-konsep ini.
sumber
Dalam JavaScript variabel statis secara default. Contoh :
Nilai x bertambah 1 setiap 1000 milidetik.
Ini akan mencetak 1,2,3 dan seterusnya
sumber
Ada pendekatan lain, yang memecahkan persyaratan saya setelah menelusuri utas ini. Tergantung pada apa yang ingin Anda capai dengan "variabel statis".
Sesi properti global, Storage atau localStorage, memungkinkan data disimpan selama umur sesi, atau untuk periode yang lebih lama tanpa batas hingga masing-masing dihapus secara eksplisit. Ini memungkinkan data untuk dibagikan di antara semua jendela, bingkai, panel tab, popup, dll dari halaman / aplikasi Anda dan jauh lebih kuat daripada "variabel statis / global" sederhana dalam satu segmen kode.
Itu menghindari semua kerumitan dengan ruang lingkup, seumur hidup, semantik, dinamika dll dari variabel global tingkat atas, yaitu Window.myglobal. Tidak tahu seberapa efisien itu, tetapi itu tidak penting untuk jumlah data yang sederhana, diakses dengan kecepatan sedang.
Mudah diakses sebagai "sessionStorage.mydata = apa pun" dan diambil dengan cara yang sama. Lihat "JavaScript: Panduan Definitif, Edisi Keenam", David Flanagan, ISBN: 978-0-596-80552-4, Bab 20, bagian 20.1. Ini mudah diunduh sebagai PDF dengan pencarian sederhana, atau dalam langganan O'Reilly Safaribooks Anda (senilai dengan emas).
sumber
Fungsi / kelas hanya memungkinkan konstruktor tunggal untuk cakupan objeknya.
Function Hoisting, declarations & expressions
Penutupan - salinan penutupan berfungsi dengan data yang disimpan.
Kelas Fungsi ES5 : using Object.defineProperty (O, P, Attributes)
Dibuat beberapa metode dengan menggunakan `` , Sehingga setiap kali dapat memahami fungsi kelas dengan mudah.
Cuplikan kode di bawah ini untuk menguji tentang Setiap instance memiliki salinannya sendiri anggota instance dan anggota statis umum.
Kelas ES6: Kelas ES2015 adalah gula sederhana di atas pola OO berbasis prototipe. Memiliki satu bentuk deklaratif yang nyaman membuat pola kelas lebih mudah digunakan, dan mendorong interoperabilitas. Kelas mendukung warisan berbasis prototipe, panggilan super, contoh dan metode statis dan konstruktor.
Contoh : lihat posting saya sebelumnya.
sumber
Ada 4 cara untuk meniru fungsi-variabel statis lokal di Javascript.
Metode 1: Menggunakan properti objek fungsi (didukung di browser lama)
Metode 2: Menggunakan penutupan, varian 1 (didukung di browser lama)
Metode 3: Menggunakan penutupan, varian 2 (juga didukung di browser lama)
Metode 4: Menggunakan penutupan, varian 3 (membutuhkan dukungan untuk EcmaScript 2015)
sumber
Anda dapat menentukan fungsi statis dalam JavaScript menggunakan
static
kata kunci:Pada tulisan ini, Anda masih tidak dapat mendefinisikan properti statis (selain fungsi) di dalam kelas. Properti statis masih merupakan proposal Tahap 3 , yang berarti mereka belum menjadi bagian dari JavaScript. Namun, tidak ada yang menghentikan Anda dari hanya menetapkan ke kelas seperti yang Anda lakukan pada objek lain:
Catatan akhir: berhati-hatilah dalam menggunakan objek statis dengan pewarisan - semua kelas yang diwarisi berbagi salinan objek yang sama .
sumber
Dalam JavaScript, tidak ada istilah atau kata kunci statis, tetapi kita dapat menempatkan data tersebut langsung ke objek fungsi (seperti di objek lain).
sumber
Saya sering menggunakan variabel fungsi statis dan ini memalukan. JS tidak memiliki mekanisme bawaan untuk itu. Terlalu sering saya melihat kode di mana variabel dan fungsi didefinisikan dalam lingkup luar meskipun mereka hanya digunakan di dalam satu fungsi. Ini jelek, rawan kesalahan dan hanya meminta masalah ...
Saya datang dengan metode berikut:
Ini menambahkan metode 'statika' ke semua fungsi (ya, cukup santai saja), ketika dipanggil akan menambah objek kosong (_statika) ke objek fungsi dan mengembalikannya. Jika fungsi init disediakan _statics akan diatur ke init () hasilnya.
Anda kemudian dapat melakukan:
Membandingkan ini dengan IIFE yang merupakan jawaban yang benar lainnya, ini memiliki kekurangan menambahkan satu tugas dan satu jika pada setiap panggilan fungsi dan menambahkan anggota '_statics' ke fungsi, namun ada beberapa keuntungan: argumen ada di bagian atas tidak dalam fungsi internal, menggunakan 'statis' dalam kode fungsi internal secara eksplisit dengan '_s.' awalan, dan secara keseluruhan lebih mudah untuk dilihat dan dipahami.
sumber
Ringkasan:
Di
ES6
/ ES 2015class
kata kunci diperkenalkan denganstatic
kata kunci yang disertakan . Perlu diingat bahwa ini adalah gula sintaksis atas model pewarisan prototypal yang diwujudkan oleh skrip. Katastatic
kunci berfungsi dengan cara berikut untuk metode:sumber
Saya menggunakan prototipe dan cara kerjanya:
atau menggunakan pengambil statis:
sumber
Jendela tingkat vars agak seperti statika dalam arti bahwa Anda dapat menggunakan referensi langsung dan ini tersedia untuk semua bagian dari aplikasi Anda
sumber
Tidak ada yang namanya variabel statis dalam Javascript. Bahasa ini berorientasi objek berbasis prototipe, sehingga tidak ada kelas, tetapi prototipe dari mana objek "menyalin" sendiri.
Anda dapat mensimulasikan mereka dengan variabel global atau dengan prototyping (menambahkan properti ke prototipe):
sumber
Function.prototype
function circle() {}
|circle.prototype
|circle.prototype.pi = 3.14
|circle.prototype
|Function.prototype
|Function.__proto__
(jika itu yang Anda maksud)Bekerja dengan situs web MVC yang menggunakan jQuery, saya ingin memastikan tindakan AJAX dalam penangan peristiwa tertentu hanya dapat dieksekusi setelah permintaan sebelumnya selesai. Saya menggunakan variabel objek jqXHR "statis" untuk mencapai ini.
Diberikan tombol berikut:
Saya biasanya menggunakan IIFE seperti ini untuk pengendali klik saya:
sumber
Jika Anda ingin menggunakan prototipe maka ada caranya
Dengan melakukan ini, Anda akan dapat mengakses variabel penghitung dari setiap kejadian dan setiap perubahan pada properti akan segera tercermin !!
sumber