Seperti yang kita ketahui dari bab Tipe data, ada delapan tipe data dalam JavaScript. Tujuh di antaranya disebut “primitif”, karena nilainya hanya berisi satu hal (baik itu string, angka, atau apa pun).
Sebaliknya, objek digunakan untuk menyimpan kumpulan kunci dari berbagai data dan entitas yang lebih kompleks. Dalam JavaScript, objek menembus hampir setiap aspek bahasa. Jadi kita harus memahaminya terlebih dahulu sebelum mendalami hal lain.
Sebuah objek dapat dibuat dengan tanda kurung siku {…}
dengan daftar properti opsional. Properti adalah pasangan “kunci: nilai”, dengan key
berupa string (juga disebut “nama properti”), dan value
dapat berupa apa saja.
Kita dapat membayangkan sebuah objek sebagai sebuah lemari dengan file-file yang ditandatangani. Setiap bagian data disimpan dalam filenya dengan kunci. Sangat mudah untuk menemukan file berdasarkan namanya atau menambah/menghapus file.
Objek kosong (“lemari kosong”) dapat dibuat menggunakan salah satu dari dua sintaksis:
biarkan pengguna = Objek baru(); // Sintaks "konstruktor objek". biarkan pengguna = {}; // Sintaks "objek literal".
Biasanya yang digunakan adalah tanda kurung kurawal {...}
. Deklarasi itu disebut objek literal .
Kita dapat segera memasukkan beberapa properti ke dalam {...}
sebagai pasangan “kunci: nilai”:
biarkan pengguna = { // sebuah objek nama: "John", // dengan kunci "nama" menyimpan nilai "John" usia: 30 // dengan kunci "usia" nilai penyimpanan 30 };
Properti memiliki kunci (juga dikenal sebagai “nama” atau “pengidentifikasi”) sebelum titik dua ":"
dan nilai di sebelah kanannya.
Di objek user
, ada dua properti:
Properti pertama memiliki nama "name"
dan nilai "John"
.
Yang kedua memiliki nama "age"
dan nilainya 30
.
Objek user
yang dihasilkan dapat dibayangkan sebagai sebuah kabinet dengan dua file bertanda tangan yang diberi label “nama” dan “usia”.
Kami dapat menambah, menghapus, dan membaca file darinya kapan saja.
Nilai properti dapat diakses menggunakan notasi titik:
// dapatkan nilai properti dari objek: peringatan( nama pengguna ); // Yohanes peringatan( pengguna.usia ); // 30
Nilainya bisa jenis apa pun. Mari tambahkan yang boolean:
pengguna.isAdmin = benar;
Untuk menghapus properti, kita dapat menggunakan operator delete
:
hapus pengguna.usia;
Kita juga dapat menggunakan nama properti multikata, namun harus diberi tanda kutip:
biarkan pengguna = { nama: "Yohanes", usia: 30, "likes birds": true // nama properti multikata harus dikutip };
Properti terakhir dalam daftar mungkin diakhiri dengan koma:
biarkan pengguna = { nama: "Yohanes", usia: 30, }
Itu disebut koma “di belakang” atau “menggantung”. Memudahkan untuk menambah/menghapus/memindahkan properti, karena semua garis menjadi sama.
Untuk properti multikata, akses titik tidak berfungsi:
// ini akan menghasilkan kesalahan sintaksis pengguna.suka burung = benar
JavaScript tidak memahaminya. Ia berpikir bahwa kita menangani user.likes
, dan kemudian memberikan kesalahan sintaksis ketika menemukan birds
yang tidak terduga.
Titik memerlukan kunci untuk menjadi pengidentifikasi variabel yang valid. Artinya: tidak mengandung spasi, tidak dimulai dengan angka, dan tidak menyertakan karakter khusus ( $
dan _
diperbolehkan).
Ada alternatif “notasi braket persegi” yang dapat digunakan dengan string apa pun:
biarkan pengguna = {}; // mengatur pengguna["menyukai burung"] = benar; // mendapatkan alert(pengguna["suka burung"]); // BENAR // menghapus hapus pengguna["suka burung"];
Sekarang semuanya baik-baik saja. Harap perhatikan bahwa string di dalam tanda kurung diberi tanda kutip dengan benar (jenis tanda kutip apa pun bisa digunakan).
Tanda kurung siku juga menyediakan cara untuk mendapatkan nama properti sebagai hasil dari ekspresi apa pun – sebagai lawan dari string literal – seperti dari variabel sebagai berikut:
let key = "suka burung"; // sama seperti pengguna["suka burung"] = true; pengguna[kunci] = benar;
Di sini, key
variabel dapat dihitung pada saat run-time atau bergantung pada input pengguna. Dan kemudian kami menggunakannya untuk mengakses properti. Itu memberi kita banyak fleksibilitas.
Misalnya:
biarkan pengguna = { nama: "Yohanes", usia: 30 }; let key = prompt("Apa yang ingin Anda ketahui tentang pengguna?", "nama"); // akses berdasarkan variabel peringatan( pengguna[kunci] ); // John (jika masukkan "nama")
Notasi titik tidak dapat digunakan dengan cara serupa:
biarkan pengguna = { nama: "Yohanes", usia: 30 }; biarkan kunci = "nama"; peringatan( pengguna.kunci ) // tidak terdefinisi
Kita bisa menggunakan tanda kurung siku dalam literal objek, saat membuat objek. Itu disebut properti terhitung .
Misalnya:
biarkan buah = prompt("Buah apa yang harus dibeli?", "apel"); biarkan tas = { [buah]: 5, // nama properti diambil dari variabel buah }; alert( bag.apple ); // 5 jika buah = "apel"
Arti dari properti yang dihitung sederhana saja: [fruit]
artinya nama properti harus diambil dari fruit
.
Jadi, jika pengunjung memasukkan "apple"
, bag
akan menjadi {apple: 5}
.
Pada dasarnya, cara kerjanya sama dengan:
biarkan buah = prompt("Buah apa yang harus dibeli?", "apel"); biarkan tas = {}; // mengambil nama properti dari variabel buah tas[buah] = 5;
…Tapi terlihat lebih bagus.
Kita dapat menggunakan ekspresi yang lebih kompleks di dalam tanda kurung siku:
biarkan buah = 'apel'; biarkan tas = { [buah + 'Komputer']: 5 // bag.appleComputers = 5 };
Tanda kurung siku jauh lebih kuat dibandingkan notasi titik. Mereka mengizinkan nama properti dan variabel apa pun. Tapi mereka juga lebih rumit untuk ditulis.
Jadi sering kali, ketika nama properti diketahui dan sederhana, titik digunakan. Dan jika kita membutuhkan sesuatu yang lebih kompleks, kita beralih ke tanda kurung siku.
Dalam kode sebenarnya, kita sering menggunakan variabel yang ada sebagai nilai nama properti.
Misalnya:
fungsi makeUser(nama, umur) { kembali { nama: nama, usia: usia, // ...properti lainnya }; } biarkan pengguna = makeUser("John", 30); alert(nama pengguna); // Yohanes
Pada contoh di atas, properti memiliki nama yang sama dengan variabel. Kasus penggunaan pembuatan properti dari variabel sangat umum, sehingga ada singkatan nilai properti khusus untuk membuatnya lebih pendek.
Daripada name:name
kita cukup menulis name
, seperti ini:
fungsi makeUser(nama, umur) { kembali { nama, // sama dengan nama: nama umur, // sama dengan umur: umur // ... }; }
Kita dapat menggunakan properti normal dan singkatan pada objek yang sama:
biarkan pengguna = { nama, // sama dengan nama:nama usia: 30 };
Seperti yang telah kita ketahui, sebuah variabel tidak boleh memiliki nama yang sama dengan salah satu kata yang dilindungi bahasa seperti “untuk”, “biarkan”, “kembali”, dll.
Namun untuk properti objek, tidak ada batasan seperti itu:
// properti ini baik-baik saja misalkan obj = { untuk: 1, biarkan: 2, kembali: 3 }; waspada( obj.untuk + obj.let + obj.return ); // 6
Singkatnya, tidak ada batasan nama properti. Mereka dapat berupa string atau simbol apa pun (tipe khusus untuk pengidentifikasi, akan dibahas nanti).
Tipe lain secara otomatis dikonversi menjadi string.
Misalnya, angka 0
menjadi string "0"
ketika digunakan sebagai kunci properti:
misalkan obj = { 0: "tes" // sama dengan "0": "tes" }; // kedua peringatan mengakses properti yang sama (angka 0 diubah menjadi string "0") peringatan( obj["0"] ); // tes peringatan( obj[0] ); // tes (properti yang sama)
Ada masalah kecil dengan properti khusus bernama __proto__
. Kami tidak dapat menyetelnya ke nilai non-objek:
misalkan obj = {}; obj.__proto__ = 5; // berikan nomor peringatan(obj.__proto__); // [Objek Objek] - nilai adalah objek, tidak berfungsi sebagaimana mestinya
Seperti yang kita lihat dari kodenya, penugasan ke primitif 5
diabaikan.
Kita akan membahas sifat khusus __proto__
di bab selanjutnya, dan menyarankan cara untuk memperbaiki perilaku tersebut.
Fitur penting dari objek dalam JavaScript, dibandingkan dengan banyak bahasa lainnya, adalah bahwa properti apa pun dapat diakses. Tidak akan ada kesalahan jika properti tidak ada!
Membaca properti yang tidak ada hanya mengembalikan undefined
. Jadi kita dapat dengan mudah menguji apakah properti tersebut ada:
biarkan pengguna = {}; peringatan( pengguna.noSuchProperty === tidak terdefinisi ); // true berarti "tidak ada properti seperti itu"
Ada juga operator khusus "in"
untuk itu.
Sintaksnya adalah:
"kunci" pada objek
Misalnya:
biarkan pengguna = { nama: "John", umur: 30 }; alert("usia" pada pengguna); // benar, usia pengguna ada alert("blabla" pada pengguna); // salah, pengguna.blabla tidak ada
Harap dicatat bahwa di in
kiri harus ada nama properti . Itu biasanya string yang dikutip.
Jika kita menghilangkan tanda kutip, itu berarti suatu variabel harus berisi nama sebenarnya yang akan diuji. Misalnya:
biarkan pengguna = { usia: 30 }; biarkan kunci = "umur"; waspada(masukkan pengguna); // benar, properti "usia" ada
Mengapa operator in
ada? Bukankah cukup membandingkannya dengan undefined
?
Ya, seringkali perbandingan dengan undefined
berfungsi dengan baik. Namun ada kasus khusus ketika gagal, tetapi "in"
berfungsi dengan benar.
Itu terjadi ketika properti objek ada, tetapi menyimpan undefined
:
misalkan obj = { tes: tidak terdefinisi }; alert( obj.test ); // tidak terdefinisi, jadi - tidak ada properti seperti itu? alert("tes" di obj); // benar, properti itu memang ada!
Pada kode di atas, properti obj.test
secara teknis ada. Jadi operator in
berfungsi dengan benar.
Situasi seperti ini sangat jarang terjadi, karena undefined
tidak boleh ditetapkan secara eksplisit. Kami kebanyakan menggunakan null
untuk nilai "tidak diketahui" atau "kosong". Jadi operator in
adalah tamu eksotik dalam kode.
Untuk menelusuri semua kunci suatu objek, terdapat bentuk perulangan khusus: for..in
. Ini adalah hal yang sama sekali berbeda dari konstruksi for(;;)
yang kita pelajari sebelumnya.
Sintaksnya:
untuk (masukkan objek) { // mengeksekusi isi setiap kunci di antara properti objek }
Misalnya, mari kita tampilkan semua properti user
:
biarkan pengguna = { nama: "Yohanes", usia: 30, isAdmin: benar }; untuk (biarkan memasukkan pengguna) { // kunci peringatan( kunci ); // nama, umur, isAdmin // nilai untuk kunci peringatan( pengguna[kunci] ); // John, 30, benar }
Perhatikan bahwa semua konstruksi “untuk” memungkinkan kita mendeklarasikan variabel perulangan di dalam perulangan, seperti let key
di sini.
Selain itu, kita juga dapat menggunakan nama variabel lain di sini, bukan key
. Misalnya, "for (let prop in obj)"
juga banyak digunakan.
Apakah benda dipesan? Dengan kata lain, jika kita mengulang suatu objek, apakah kita mendapatkan semua properti dalam urutan yang sama saat ditambahkan? Bisakah kita mengandalkan ini?
Jawaban singkatnya adalah: “diurutkan dengan cara khusus”: properti bilangan bulat diurutkan, properti lainnya muncul dalam urutan pembuatan. Detailnya menyusul.
Sebagai contoh, mari kita perhatikan sebuah objek dengan kode telepon:
biarkan kode = { "49": "Jerman", "41": "Swiss", "44": "Inggris Raya", // .., "1": "AS" }; for (biarkan kode dalam kode) { peringatan(kode); // 1, 41, 44, 49 }
Objek tersebut dapat digunakan untuk menyarankan daftar opsi kepada pengguna. Jika kami membuat situs terutama untuk pemirsa Jerman maka kami mungkin ingin 49
menjadi yang pertama.
Namun jika kita menjalankan kodenya, kita akan melihat gambaran yang sangat berbeda:
AS (1) menjadi yang pertama
lalu Swiss (41) dan seterusnya.
Kode telepon disusun dalam urutan menaik, karena bilangan bulat. Jadi kita melihat 1, 41, 44, 49
.
Properti bilangan bulat? Apa itu?
Istilah “properti bilangan bulat” di sini berarti string yang dapat dikonversi ke dan dari bilangan bulat tanpa perubahan.
Jadi, "49"
adalah nama properti bilangan bulat, karena ketika diubah menjadi bilangan bulat dan sebaliknya, tetap sama. Namun "+49"
dan "1.2"
bukan:
// Number(...) secara eksplisit dikonversi menjadi angka // Math.trunc adalah fungsi bawaan yang menghilangkan bagian desimal alert( String(Matematika.trunc(Nomor("49"))) ); // "49", sama, properti integer alert( String(Matematika.trunc(Nomor("+49"))) ); // "49", tidak sama "+49" ⇒ bukan properti bilangan bulat alert( String(Matematika.trunc(Nomor("1.2"))) ); // "1", tidak sama "1.2" ⇒ bukan properti bilangan bulat
…Sebaliknya, jika kuncinya bukan bilangan bulat, maka kunci tersebut dicantumkan dalam urutan pembuatannya, misalnya:
biarkan pengguna = { nama: "Yohanes", nama keluarga: "Smith" }; pengguna.usia = 25; // tambahkan satu lagi // properti non-integer dicantumkan dalam urutan pembuatan for (biarkan prop masuk pengguna) { peringatan(menopang); // nama, nama keluarga, umur }
Jadi, untuk memperbaiki masalah kode telepon, kita bisa “menipu” dengan membuat kode-kode tersebut bukan bilangan bulat. Menambahkan tanda tambah "+"
sebelum setiap kode sudah cukup.
Seperti ini:
biarkan kode = { "+49": "Jerman", "+41": "Swiss", "+44": "Inggris Raya", // .., "+1": "AS" }; for (biarkan kode dalam kode) { peringatan( +kode ); // 49, 41, 44, 1 }
Sekarang berfungsi sebagaimana mestinya.
Objek adalah array asosiatif dengan beberapa fitur khusus.
Mereka menyimpan properti (pasangan nilai kunci), di mana:
Kunci properti harus berupa string atau simbol (biasanya string).
Nilai dapat berupa jenis apa pun.
Untuk mengakses properti, kita dapat menggunakan:
Notasi titik: obj.property
.
Notasi tanda kurung siku obj["property"]
. Tanda kurung siku memungkinkan pengambilan kunci dari variabel, seperti obj[varWithKey]
.
Operator tambahan:
Untuk menghapus properti: delete obj.prop
.
Untuk memeriksa apakah properti dengan kunci yang diberikan ada: "key" in obj
.
Untuk mengulangi suatu objek: perulangan for (let key in obj)
.
Apa yang telah kita pelajari dalam bab ini disebut “objek biasa”, atau hanya Object
.
Ada banyak jenis objek lain di JavaScript:
Array
untuk menyimpan kumpulan data yang dipesan,
Date
untuk menyimpan informasi tentang tanggal dan waktu,
Error
untuk menyimpan informasi tentang kesalahan.
…Dan sebagainya.
Mereka memiliki ciri-ciri khusus yang akan kita pelajari nanti. Kadang-kadang orang mengatakan sesuatu seperti "Jenis array" atau "Jenis tanggal", tetapi secara formal keduanya bukan tipe mereka sendiri, tetapi termasuk dalam satu tipe data "objek". Dan mereka memperluasnya dengan berbagai cara.
Objek dalam JavaScript sangat kuat. Di sini kita baru saja menggores permukaan dari sebuah topik yang sangat besar. Kita akan bekerja lebih dekat dengan objek dan mempelajari lebih lanjut tentang objek tersebut di bagian selanjutnya dari tutorial.
pentingnya: 5
Tulis kodenya, satu baris untuk setiap tindakan:
Buat user
objek kosong.
Tambahkan name
properti dengan nilai John
.
Tambahkan surname
properti dengan nilai Smith
.
Ubah nilai name
menjadi Pete
.
Hapus name
properti dari objek.
biarkan pengguna = {}; nama pengguna = "John"; pengguna.nama belakang = "Smith"; pengguna.nama = "Pete"; hapus nama pengguna;
pentingnya: 5
Tulis fungsi isEmpty(obj)
yang mengembalikan true
jika objek tidak memiliki properti, false
jika tidak.
Seharusnya bekerja seperti itu:
biarkan jadwal = {}; waspada( isEmpty(jadwal) ); // BENAR jadwal["8:30"] = "bangun"; waspada( isEmpty(jadwal) ); // PALSU
Buka kotak pasir dengan tes.
Ulangi saja objeknya dan segera return false
jika ada setidaknya satu properti.
fungsi isEmpty(obj) { untuk (biarkan memasukkan objek) { // jika perulangan sudah dimulai, ada properti kembali salah; } kembali benar; }
Buka solusi dengan pengujian di kotak pasir.
pentingnya: 5
Kami memiliki objek yang menyimpan gaji tim kami:
misalkan gaji = { Yohanes: 100, Ann: 160, Pete: 130 }
Tulis kode untuk menjumlahkan semua gaji dan menyimpannya dalam variabel sum
. Seharusnya 390
pada contoh di atas.
Jika salaries
kosong, maka hasilnya harus 0
.
misalkan gaji = { Yohanes: 100, Ann: 160, Pete: 130 }; misalkan jumlah = 0; untuk (biarkan memasukkan gaji) { jumlah += gaji[kunci]; } peringatan(jumlah); // 390
pentingnya: 3
Buat fungsi multiplyNumeric(obj)
yang mengalikan semua nilai properti numerik obj
dengan 2
.
Misalnya:
// sebelum panggilan biarkan menu = { lebar: 200, tinggi: 300, judul: "Menu saya" }; kalikanNumerik(menu); // setelah panggilan menu = { lebar: 400, tinggi: 600, judul: "Menu saya" };
Harap dicatat bahwa multiplyNumeric
tidak perlu mengembalikan apa pun. Itu harus memodifikasi objek di tempatnya.
PS Gunakan typeof
untuk memeriksa nomor di sini.
Buka kotak pasir dengan tes.
fungsi perkalianNumerik(obj) { untuk (biarkan memasukkan objek) { if (typeof obj[key] == 'angka') { obj[kunci] *= 2; } } }
Buka solusi dengan pengujian di kotak pasir.