Ingat kotak P3K dari bab 3? . Enkapsulasi, atau pemotongan seperti itu, di mana kita memperlakukan koleksi sebagai tunggal, merupakan bagian penting dari cara kita sebagai manusia mengatasi informasi yang kompleks, baik dalam bahasa maupun dalam memori. Ketika diperlukan, kita dapat mempertimbangkan elemen-elemen yang menyusun kit. antiseptik, plester, perban, dan sebagainya
Di sini kami baru saja menggunakan Ekspresi Fungsi untuk membuat fungsi dan menugaskannya ke properti let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!2 objek
Maka kita bisa menyebutnya sebagai let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!3. Pengguna sekarang dapat berbicara
Fungsi yang merupakan properti dari suatu objek disebut metodenya
Jadi, di sini kita punya metode let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!4 dari objek let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!1
Tentu saja, kita bisa menggunakan fungsi yang telah dideklarasikan sebagai metode, seperti ini
let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!_
Pemrograman berorientasi objek
Saat kita menulis kode kita menggunakan objek untuk mewakili entitas, singkatnya itu disebut pemrograman berorientasi objek. “OOP”
OOP adalah hal yang besar, ilmu tersendiri yang menarik. Bagaimana cara memilih entitas yang tepat? . Elemen Perangkat Lunak Berorientasi Objek yang Dapat Digunakan Kembali” oleh E. Gama, R. Helm, R. Johnson, J. Vissides atau "Analisis dan Desain Berorientasi Objek dengan Aplikasi" oleh G. Booch, dan lainnya
Ada sintaks yang lebih pendek untuk metode dalam objek literal
// these objects do the same user = { sayHi: function() { alert("Hello"); } }; // method shorthand looks better, right? user = { sayHi() { // same as "sayHi: function(){...}" alert("Hello"); } };
Seperti yang ditunjukkan, kita dapat menghilangkan let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!_6 dan hanya menulis let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!7
Sejujurnya, notasi tidak sepenuhnya identik. Ada perbedaan halus yang terkait dengan pewarisan objek (akan dibahas nanti), tetapi untuk saat ini hal itu tidak menjadi masalah. Di hampir semua kasus, sintaks yang lebih pendek lebih disukai
Biasanya metode objek perlu mengakses informasi yang disimpan dalam objek untuk melakukan tugasnya
Misalnya, kode di dalam let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!_3 mungkin memerlukan nama let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!1
Untuk mengakses objek, metode dapat menggunakan kata kunci let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0
Nilai let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 adalah objek "sebelum titik", yang digunakan untuk memanggil metode
Contohnya
let user = { name: "John", age: 30, sayHi() { // "this" is the "current object" alert(this.name); } }; user.sayHi(); // John
Di sini selama pelaksanaan let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!_3, nilai let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 akan menjadi let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!1
Secara teknis, ini juga memungkinkan untuk mengakses objek tanpa let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0, dengan merujuknya melalui variabel luar
let user = { name: "John", age: 30, sayHi() { alert(user.name); // "user" instead of "this" } };
… Tapi kode seperti itu tidak bisa diandalkan. Jika kami memutuskan untuk menyalin let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!_1 ke variabel lain, mis. g. let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!_7 dan menimpa let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!1 dengan sesuatu yang lain, maka itu akan mengakses objek yang salah
Itu ditunjukkan di bawah ini
let user = { name: "John", age: 30, sayHi() { alert( user.name ); // leads to an error } }; let admin = user; user = null; // overwrite to make things obvious admin.sayHi(); // TypeError: Cannot read property 'name' of null
Jika kita menggunakan let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!_9 alih-alih // these objects do the same user = { sayHi: function() { alert("Hello"); } }; // method shorthand looks better, right? user = { sayHi() { // same as "sayHi: function(){...}" alert("Hello"); } };0 di dalam // these objects do the same user = { sayHi: function() { alert("Hello"); } }; // method shorthand looks better, right? user = { sayHi() { // same as "sayHi: function(){...}" alert("Hello"); } };1, maka kode akan berfungsi
Dalam JavaScript, kata kunci let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 berperilaku tidak seperti kebanyakan bahasa pemrograman lainnya. Itu dapat digunakan dalam fungsi apa pun, meskipun itu bukan metode objek
Tidak ada kesalahan sintaks dalam contoh berikut
function sayHi() { alert( this.name ); }
Nilai let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!_0 dievaluasi selama run-time, tergantung pada konteksnya
Misalnya, di sini fungsi yang sama ditugaskan ke dua objek berbeda dan memiliki "ini" yang berbeda dalam panggilan
let user = { name: "John" }; let admin = { name: "Admin" }; function sayHi() { alert( this.name ); } // use the same function in two objects user.f = sayHi; admin.f = sayHi; // these calls have different this // "this" inside the function is the object "before the dot" user.f(); // John (this == user) admin.f(); // Admin (this == admin) admin['f'](); // Admin (dot or square brackets access the method – doesn't matter)
Aturannya sederhana. jika // these objects do the same user = { sayHi: function() { alert("Hello"); } }; // method shorthand looks better, right? user = { sayHi() { // same as "sayHi: function(){...}" alert("Hello"); } };_4 dipanggil, maka let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 adalah // these objects do the same user = { sayHi: function() { alert("Hello"); } }; // method shorthand looks better, right? user = { sayHi() { // same as "sayHi: function(){...}" alert("Hello"); } };6 selama panggilan // these objects do the same user = { sayHi: function() { alert("Hello"); } }; // method shorthand looks better, right? user = { sayHi() { // same as "sayHi: function(){...}" alert("Hello"); } };7. Jadi let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!_1 atau // these objects do the same user = { sayHi: function() { alert("Hello"); } }; // method shorthand looks better, right? user = { sayHi() { // same as "sayHi: function(){...}" alert("Hello"); } };9 pada contoh di atas
Memanggil tanpa objek. let user = { name: "John", age: 30, sayHi() { // "this" is the "current object" alert(this.name); } }; user.sayHi(); // John0
Kami bahkan dapat memanggil fungsi tanpa objek sama sekali
function sayHi() { alert(this); } sayHi(); // undefined
Dalam hal ini let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 adalah let user = { name: "John", age: 30, sayHi() { // "this" is the "current object" alert(this.name); } }; user.sayHi(); // John2 dalam mode ketat. Jika kami mencoba mengakses let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!9, akan terjadi kesalahan
Dalam mode non-ketat nilai let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 dalam kasus seperti itu akan menjadi objek global (let user = { name: "John", age: 30, sayHi() { // "this" is the "current object" alert(this.name); } }; user.sayHi(); // John5 di browser, kita akan membahasnya nanti di bab Objek global). Ini adalah perilaku historis yang let user = { name: "John", age: 30, sayHi() { // "this" is the "current object" alert(this.name); } }; user.sayHi(); // John6 diperbaiki
Biasanya panggilan seperti itu adalah kesalahan pemrograman. Jika ada let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 di dalam suatu fungsi, fungsi tersebut diharapkan dipanggil dalam konteks objek
Konsekuensi dari let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 yang tidak terikat
Jika Anda berasal dari bahasa pemrograman lain, maka Anda mungkin terbiasa dengan gagasan "let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 terikat", di mana metode yang didefinisikan dalam suatu objek selalu memiliki let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 referensi objek itu
Dalam JavaScript let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 adalah "gratis", nilainya dievaluasi pada waktu panggilan dan tidak bergantung pada di mana metode dideklarasikan, melainkan pada objek apa yang "sebelum titik"
Konsep run-time dievaluasi let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!_0 memiliki plus dan minus. Di satu sisi, suatu fungsi dapat digunakan kembali untuk objek yang berbeda. Di sisi lain, fleksibilitas yang lebih besar menciptakan lebih banyak kemungkinan kesalahan
Di sini posisi kita bukan untuk menilai apakah keputusan desain bahasa ini baik atau buruk. Kami akan mengerti bagaimana bekerja dengannya, bagaimana mendapatkan keuntungan dan menghindari masalah
Fungsi panah itu spesial. mereka tidak memiliki "milik" let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0. Jika kita mereferensikan let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 dari fungsi seperti itu, ini diambil dari fungsi luar "normal"
Misalnya, di sini let user = { name: "John", age: 30, sayHi() { alert(user.name); // "user" instead of "this" } };_5 menggunakan let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 dari metode luar let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!3
let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!0
Itu adalah fitur khusus dari fungsi panah, ini berguna ketika kita sebenarnya tidak ingin memiliki let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 yang terpisah, melainkan mengambilnya dari konteks luar. Nanti di bab Fungsi panah ditinjau kembali, kita akan masuk lebih dalam ke fungsi panah
- Fungsi yang disimpan dalam properti objek disebut "metode"
- Metode memungkinkan objek untuk "bertindak" seperti let user = { name: "John", age: 30, sayHi() { alert(user.name); // "user" instead of "this" } };9
- Metode dapat mereferensikan objek sebagai let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0
Nilai let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!_0 didefinisikan pada saat run-time
- Saat sebuah fungsi dideklarasikan, ia mungkin menggunakan let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0, tetapi let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 itu tidak memiliki nilai hingga fungsi tersebut dipanggil
- Suatu fungsi dapat disalin di antara objek
- Ketika suatu fungsi dipanggil dalam sintaks "metode". let user = { name: "John", age: 30, sayHi() { alert( user.name ); // leads to an error } }; let admin = user; user = null; // overwrite to make things obvious admin.sayHi(); // TypeError: Cannot read property 'name' of null4, nilai let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0 selama panggilan adalah let user = { name: "John", age: 30, sayHi() { alert( user.name ); // leads to an error } }; let admin = user; user = null; // overwrite to make things obvious admin.sayHi(); // TypeError: Cannot read property 'name' of null6
Harap dicatat bahwa fungsi panah itu spesial. mereka tidak memiliki let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!0. Ketika let user = { // ... }; // first, declare function sayHi() { alert("Hello!"); } // then add as a method user.sayHi = sayHi; user.sayHi(); // Hello!_0 diakses di dalam fungsi panah, itu diambil dari luar