Sintaks {...}
reguler memungkinkan kita membuat satu objek. Namun seringkali kita perlu membuat banyak objek serupa, seperti beberapa pengguna atau item menu dan sebagainya.
Itu bisa dilakukan dengan menggunakan fungsi konstruktor dan operator "new"
.
Fungsi konstruktor secara teknis adalah fungsi reguler. Namun ada dua konvensi:
Mereka diberi nama dengan huruf kapital terlebih dahulu.
Mereka harus dieksekusi hanya dengan operator "new"
.
Misalnya:
fungsi Pengguna(nama) { ini.nama = nama; ini.isAdmin = salah; } biarkan pengguna = Pengguna baru("Jack"); alert(nama pengguna); // Mendongkrak alert(pengguna.isAdmin); // PALSU
Ketika suatu fungsi dijalankan dengan new
, ia melakukan langkah-langkah berikut:
Objek kosong baru dibuat dan ditugaskan ke this
.
Badan fungsi dijalankan. Biasanya ia memodifikasi this
, menambahkan properti baru ke dalamnya.
Nilai this
dikembalikan.
Dengan kata lain, new User(...)
melakukan sesuatu seperti:
fungsi Pengguna(nama) { // ini = {}; (secara implisit) // tambahkan properti ke dalamnya ini.nama = nama; ini.isAdmin = salah; // kembalikan ini; (secara implisit) }
Jadi let user = new User("Jack")
memberikan hasil yang sama seperti:
biarkan pengguna = { nama: "Jack", isAdmin: salah };
Sekarang jika kita ingin membuat pengguna lain, kita dapat memanggil new User("Ann")
, new User("Alice")
dan seterusnya. Jauh lebih pendek dibandingkan menggunakan literal setiap saat, dan juga mudah dibaca.
Itulah tujuan utama konstruktor – untuk mengimplementasikan kode pembuatan objek yang dapat digunakan kembali.
Mari kita perhatikan sekali lagi – secara teknis, fungsi apa pun (kecuali fungsi panah, karena tidak memiliki this
) dapat digunakan sebagai konstruktor. Itu dapat dijalankan dengan new
, dan itu akan menjalankan algoritma di atas. “Huruf kapital dulu” adalah kesepakatan bersama, untuk memperjelas bahwa suatu fungsi harus dijalankan dengan new
.
fungsi baru() { … }
Jika kita mempunyai banyak baris kode tentang pembuatan satu objek kompleks, kita dapat membungkusnya dalam fungsi konstruktor yang segera dipanggil, seperti ini:
// membuat suatu fungsi dan segera memanggilnya dengan yang baru biarkan pengguna = fungsi baru() { this.nama = "John"; ini.isAdmin = salah; // ...kode lain untuk pembuatan pengguna // mungkin logika dan pernyataan yang rumit // variabel lokal dll };
Konstruktor ini tidak dapat dipanggil lagi, karena tidak disimpan dimanapun, hanya dibuat dan dipanggil. Jadi trik ini bertujuan untuk merangkum kode yang membangun objek tunggal, tanpa digunakan kembali di masa mendatang.
Hal-hal tingkat lanjut
Sintaks dari bagian ini jarang digunakan, lewati saja kecuali Anda ingin mengetahui semuanya.
Di dalam suatu fungsi, kita dapat memeriksa apakah fungsi tersebut dipanggil dengan new
atau tanpa fungsi, menggunakan properti new.target
khusus.
Itu tidak terdefinisi untuk panggilan biasa dan sama dengan fungsinya jika dipanggil dengan new
:
fungsi Pengguna() { alert(baru.target); } // tanpa "baru": Pengguna(); // belum diartikan // dengan "baru": Pengguna baru(); // fungsi Pengguna { ... }
Itu dapat digunakan di dalam fungsi untuk mengetahui apakah itu dipanggil dengan new
, "dalam mode konstruktor", atau tanpa itu, "dalam mode reguler".
Kami juga dapat melakukan panggilan new
dan reguler untuk melakukan hal yang sama, seperti ini:
fungsi Pengguna(nama) { if (!new.target) {// jika Anda menjalankan saya tanpa yang baru kembalikan Pengguna baru (nama); // ...Aku akan menambahkan yang baru untukmu } ini.nama = nama; } biarkan john = Pengguna("John"); // mengalihkan panggilan ke Pengguna baru alert(john.nama); // Yohanes
Pendekatan ini terkadang digunakan di perpustakaan untuk membuat sintaksis lebih fleksibel. Sehingga orang dapat memanggil fungsi tersebut dengan atau tanpa new
, dan fungsi tersebut tetap berfungsi.
Mungkin bukan hal yang baik untuk digunakan di mana pun, karena menghilangkan new
akan membuat apa yang terjadi menjadi kurang jelas. Dengan new
kita semua mengetahui bahwa objek baru sedang dibuat.
Biasanya, konstruktor tidak memiliki pernyataan return
. Tugas mereka adalah menulis semua hal yang diperlukan ke dalam this
, dan secara otomatis menjadi hasilnya.
Namun jika ada pernyataan return
, maka aturannya sederhana:
Jika return
dipanggil dengan suatu objek, maka objek tersebut dikembalikan sebagai ganti this
.
Jika return
dipanggil dengan primitif, maka akan diabaikan.
Dengan kata lain, return
dengan suatu objek mengembalikan objek itu, dalam semua kasus lainnya, this
dikembalikan.
Misalnya, di sini return
menimpa this
dengan mengembalikan sebuah objek:
fungsi Pengguna Besar() { this.nama = "John"; return { nama: "Godzilla" }; // <-- mengembalikan objek ini } peringatan( Pengguna Besar baru().nama ); // Godzilla, dapatkan benda itu
Dan inilah contoh dengan return
kosong (atau kita dapat menempatkan primitif setelahnya, tidak masalah):
fungsi Pengguna Kecil() { this.nama = "John"; kembali; // <-- mengembalikan ini } peringatan( Pengguna Kecil baru().nama ); // Yohanes
Biasanya konstruktor tidak memiliki pernyataan return
. Di sini kami menyebutkan perilaku khusus dengan mengembalikan objek terutama demi kelengkapan.
Menghilangkan tanda kurung
Ngomong-ngomong, kita bisa menghilangkan tanda kurung setelah new
:
biarkan pengguna = Pengguna baru; // <-- tanpa tanda kurung // sama dengan biarkan pengguna = Pengguna baru();
Menghilangkan tanda kurung di sini tidak dianggap sebagai “gaya yang baik”, tetapi sintaksisnya diizinkan oleh spesifikasi.
Menggunakan fungsi konstruktor untuk membuat objek memberikan banyak fleksibilitas. Fungsi konstruktor mungkin memiliki parameter yang menentukan cara membuat objek, dan apa yang dimasukkan ke dalamnya.
Tentu saja, kita tidak hanya dapat menambahkan this
, tetapi juga metode.
Misalnya, new User(name)
di bawah ini membuat objek dengan name
tertentu dan metode sayHi
:
fungsi Pengguna(nama) { ini.nama = nama; ini.sayHi = fungsi() { alert("Nama saya : " + nama ini ); }; } biarkan john = Pengguna baru("John"); john.sayHi(); // Nama saya: John /* Yohanes = { nama: "Yohanes", sapa: fungsi() { ... } } */
Untuk membuat objek yang kompleks, ada sintaksis yang lebih canggih, yaitu kelas, yang akan kita bahas nanti.
Fungsi konstruktor atau, singkatnya, konstruktor, adalah fungsi biasa, namun ada kesepakatan umum untuk menamainya dengan huruf kapital terlebih dahulu.
Fungsi konstruktor hanya boleh dipanggil menggunakan new
. Panggilan seperti itu menyiratkan pembuatan this
yang kosong di awal dan mengembalikan yang terisi di akhir.
Kita dapat menggunakan fungsi konstruktor untuk membuat beberapa objek serupa.
JavaScript menyediakan fungsi konstruktor untuk banyak objek bahasa bawaan: seperti Date
untuk tanggal, Set
untuk set, dan lainnya yang ingin kita pelajari.
Objek, kami akan kembali!
Dalam bab ini kita hanya membahas dasar-dasar tentang objek dan konstruktor. Mereka penting untuk mempelajari lebih lanjut tentang tipe data dan fungsi di bab berikutnya.
Setelah kita mempelajarinya, kita kembali ke objek dan membahasnya secara mendalam di bab Prototipe, Warisan, dan Kelas.
pentingnya: 2
Apakah mungkin membuat fungsi A
dan B
sehingga new A() == new B()
?
fungsi A() { ... } fungsi B() { ... } misalkan a = baru A(); misalkan b = baru B(); waspada( a == b ); // BENAR
Jika ya, berikan contoh kodenya.
Ya, itu mungkin.
Jika suatu fungsi mengembalikan suatu objek maka new
mengembalikannya, bukan this
.
Jadi mereka dapat, misalnya, mengembalikan objek yang ditentukan secara eksternal obj
:
misalkan obj = {}; fungsi A() { mengembalikan objek; } fungsi B() { mengembalikan objek; } peringatan( baru A() == baru B() ); // BENAR
pentingnya: 5
Buat Calculator
fungsi konstruktor yang membuat objek dengan 3 metode:
read()
meminta dua nilai dan menyimpannya sebagai properti objek dengan nama a
dan b
masing-masing.
sum()
mengembalikan jumlah properti ini.
mul()
mengembalikan produk perkalian dari properti ini.
Misalnya:
biarkan kalkulator = Kalkulator baru(); kalkulator.read(); alert("Jumlah = "+kalkulator.jumlah() ); alert( "Mul=" + kalkulator.mul() );
Jalankan demonya
Buka kotak pasir dengan tes.
fungsi Kalkulator() { ini.baca = fungsi() { ini.a = +prompt('a?', 0); this.b = +prompt('b?', 0); }; ini.jumlah = fungsi() { kembalikan ini.a + ini.b; }; ini.mul = fungsi() { kembalikan ini.a * ini.b; }; } biarkan kalkulator = Kalkulator baru(); kalkulator.read(); alert("Jumlah = "+kalkulator.jumlah() ); alert( "Mul=" + kalkulator.mul() );
Buka solusi dengan pengujian di kotak pasir.
pentingnya: 5
Buat fungsi konstruktor Accumulator(startingValue)
.
Objek yang dibuatnya harus:
Simpan “nilai saat ini” di properti value
. Nilai awal disetel ke argumen konstruktor startingValue
.
Metode read()
harus menggunakan prompt
untuk membaca nomor baru dan menambahkannya ke value
.
Dengan kata lain, properti value
adalah jumlah semua nilai yang dimasukkan pengguna dengan nilai awal startingValue
.
Berikut demo kodenya:
biarkan akumulator = Akumulator baru(1); // nilai awal 1 akumulator.read(); // menambahkan nilai yang dimasukkan pengguna akumulator.read(); // menambahkan nilai yang dimasukkan pengguna alert(akumulator.nilai); // menunjukkan jumlah dari nilai-nilai ini
Jalankan demonya
Buka kotak pasir dengan tes.
akumulator fungsi(nilai awal) { this.value = nilai awal; ini.baca = fungsi() { this.value += +prompt('Berapa banyak yang harus ditambahkan?', 0); }; } biarkan akumulator = Akumulator baru(1); akumulator.read(); akumulator.read(); alert(akumulator.nilai);
Buka solusi dengan pengujian di kotak pasir.