Beberapa mode pembuatan objek yang umum digunakan
Buat dengan kata kunci baru
Cara paling mendasar untuk membuat objek tidak lebih dari apa yang dikatakan sebagian besar bahasa: Jika Anda tidak memiliki objek, Anda bisa mendapatkan yang baru!
var gf = objek baru (); gf.name = "tangwei"; gf.bar = "c ++"; gf.saywhat = function () {console.log (this.name+"Sad: love you forever");}Buat dengan literal
Ini tampaknya benar, tetapi bagaimana cara geek seperti cara yang kompleks dan tingkat rendah untuk mendefinisikan variabel? Sebagai bahasa skrip, ia harus memiliki gaya yang sama dengan saudara -saudara lain, sehingga cara mendefinisikan objek literal muncul:
var gf = {name: "tangwei", bar: "c ++", katakan apa: function () {console.log (this.name+"Sad: love you forever"); }}Model pabrik
Sebenarnya, ini adalah metode definisi objek yang paling umum digunakan dalam kenyataan, tetapi apa yang harus saya lakukan jika saya memiliki banyak objek dengan atribut yang sama (menarik untuk memikirkannya ...)? Jika satu definisi dibuat satu per satu, sejumlah besar kode akan dihasilkan. Mengapa tidak membangun pabrik dan massa menghasilkan benda kita? Jadi, bayi tiup pertama di dunia Javascript. . . Tidak, "model pabrik" lahir!
fungsi creategf (name, bar) {var o = objek baru (); o.name = nama; o.bar = bar; o.saywhat = function () {alert (this.name + "Sad: Love You Forever"); } return o;} var gf1 = creategf ("bingbing", "d"); var gf2 = creategf ("mimi", "a");Konstruktor
Pola pabrik memecahkan masalah membuat beberapa objek serupa, tetapi masalahnya muncul lagi. Semua objek ini dibentuk oleh objek. Bagaimana cara membedakan jenis objek mereka? Saat ini, kita perlu beralih ke mode lain, mode konstruktor:
fungsi gf (name, bar) {this.name = name; this.bar = bar; ini. }} var gf1 = GF baru ("vivian", "f"); var gf2 = GF baru ("vivian2", "f");Di sini kami menggunakan konstruktor yang dimulai dengan huruf kapital untuk menggantikan creategf dalam contoh di atas. Perhatikan bahwa huruf pertama konstruktor harus dikapitalisasi sesuai dengan konvensi. Di sini kami membuat objek baru, lalu menetapkan ruang lingkup konstruktor ke objek baru, dan memanggil metode dalam konstruktor.
Tampaknya tidak ada yang salah dengan metode di atas, tetapi kita dapat menemukan bahwa metode Saypa dalam konstruktor yang disebut dalam dua instance bukanlah contoh fungsi yang sama:
console.log (gf1.saywhat == gf2.saywhat); //PALSU
Memanggil metode yang sama tetapi menyatakan berbagai contoh adalah pemborosan sumber daya. Kita dapat mengoptimalkan pernyataan fungsi Saywhat di luar konstruktor:
fungsi gf (name, bar) {this.name = name; this.bar = bar; ini.Ini memecahkan masalah mendefinisikan contoh metode yang sama beberapa kali, tetapi masalah baru muncul lagi. Pepatah yang kami tentukan adalah metode ruang lingkup global, tetapi metode ini tidak dapat dipanggil secara langsung, yang sedikit kontradiktif. Bagaimana cara lebih mendefinisikan objek dengan enkapsulasi tertentu? Mari kita lihat pola objek prototipe JavaScript.
Pola objek prototipe
Memahami objek prototipe
Saat kami membuat fungsi, fungsi akan memiliki atribut prototipe, yang menunjuk ke objek prototipe fungsi yang dibuat melalui konstruktor. Dalam istilah awam, objek prototipe adalah objek dalam memori yang menyediakan properti dan metode bersama untuk objek lain.
Dalam mode prototipe, tidak perlu mendefinisikan atribut instance dalam konstruktor, dan informasi atribut dapat langsung ditetapkan ke objek prototipe:
fungsi gf () {gf.prototype.name = "vivian"; Gf.prototype.bar = "c ++"; Gf.prototype.saywhat = function () {alert (this.name + "Sad: love you forever"); }} var gf1 = GF baru (); gf1.saywhat (); var gf2 = GF baru ();Perbedaan dari konstruktor adalah bahwa properti dan metode objek baru dapat dibagikan oleh semua contoh. Dengan kata lain, GF1 dan GF2 mengakses properti dan metode yang sama. Selain atribut yang telah kami tetapkan, ada juga beberapa atribut bawaan dalam objek prototipe. Semua objek prototipe memiliki atribut konstruktor, yang merupakan pointer ke fungsi yang berisi atribut prototipe (apakah Anda berani berkeliling titik lagi!). Melalui gambar, mari kita selesaikan proses memutar ini dengan jelas:
Semua objek memiliki objek prototipe (prototipe). Ada atribut konstruktor dalam objek prototipe yang menunjuk ke fungsi yang berisi atribut prototipe. Contoh GF GF1 dan GF2 keduanya berisi atribut internal yang menunjuk ke objek prototipe (proto muncul sebagai atribut pribadi di browser Firefox). Ketika kami mengakses atribut dalam suatu objek, pertama -tama kami akan bertanya apakah objek instance memiliki atribut ini. Jika tidak, kami akan terus mencari objek prototipe.
Menggunakan objek prototipe
Dalam contoh sebelumnya, kami memperhatikan bahwa ketika menambahkan properti ke objek prototipe, kami perlu menambahkan gf.prototype ke masing -masing. Pekerjaan ini sangat berulang. Dalam pola pembuatan objek di atas, kita tahu bahwa suatu objek dapat dibuat dalam bentuk literal. Di sini kita juga dapat memperbaikinya:
function gf () {} gf.prototype = {name: "vivian", bar: "c ++", katakan apa: function () {waspada (this.name+"Sad: Love You Forever"); }}Ada tempat di mana kita perlu memperhatikan secara khusus. Atribut konstruktor tidak lagi menunjuk ke objek GF, karena setiap kali fungsi didefinisikan, objek prototipe akan dibuat untuk itu pada saat yang sama, dan objek ini akan secara otomatis mendapatkan atribut konstruktor baru. Di tempat ini, kami menggunakan GF.Prototype untuk pada dasarnya menimpa objek prototipe asli, sehingga konstruktor juga telah menjadi atribut konstruktor dari objek baru, tidak lagi menunjuk ke GF, tetapi objek:
var gf1 = gf baru (); console.log (gf1.constructor == gf); // falseconsole.log (gf1.constructor == objek) // true
Secara umum, perubahan halus ini tidak akan memengaruhi kami, tetapi jika Anda memiliki kebutuhan khusus untuk konstruktor, kami juga dapat secara eksplisit menentukan properti konstruktor GF.Prototype:
Gf.prototype = {constructor: gf, name: "vivian", bar: "c ++", katakan apa: function () {alert (this.name+"Said: love you forever"); }} var gf1 = gf baru (); console.log (gf1.constructor == gf); // trueMelalui pemahaman awal tentang pola objek prototipe, kami menemukan bahwa semua objek instan berbagi atribut yang sama, yang merupakan fitur dasar dari pola prototipe, tetapi seringkali ini adalah "pedang bermata dua" untuk pengembang. Dalam pengembangan aktual, contoh yang kami harapkan harus memiliki atribut mereka sendiri, yang juga merupakan alasan utama mengapa beberapa orang menggunakan pola prototipe saja dalam pengembangan aktual.
Pola kombinasi konstruktor dan prototipe
Dalam pengembangan aktual, kita dapat menggunakan konstruktor untuk mendefinisikan sifat -sifat objek dan menggunakan prototipe untuk menentukan sifat dan metode bersama, sehingga kita dapat melewati parameter yang berbeda untuk membuat objek yang berbeda, sambil memiliki metode dan properti bersama.
fungsi gf (name, bar) {this.name = name; this.bar = bar;} gf.prototype = {constructor: gf, katakan apa: function () {alert (this.name + "Sad: love you forever"); }} var gf1 = GF baru ("vivian", "f"); var gf2 = GF baru ("vivian1", "c");Dalam contoh ini, kami mendefinisikan nilai properti masing -masing dari objek dalam fungsi konstruktor, dan mendefinisikan atribut konstruktor dan mengatakan fungsi apa dalam objek prototipe, sehingga tidak akan ada dampak antara atribut GF1 dan GF2. Pola ini juga merupakan metode definisi objek yang paling umum digunakan dalam pengembangan aktual, termasuk mode default yang diadopsi oleh banyak pustaka JS (bootstrap, dll.).