JavaScript adalah bahasa multi-paradigma yang mendukung pemrograman berorientasi objek dan metode dinamis yang mengikat - konsep yang kuat yang memungkinkan struktur kode JavaScript berubah selama eksekusi program. Ini memberikan peluang serius bagi pengembang, membuat bahasa menjadi fleksibel, tetapi Anda harus membayar semuanya. Dalam hal ini, Anda harus membayar dengan kelengkapan kode. Kontribusi signifikan terhadap harga ini dibuat oleh
this
, di sekitar perilaku yang telah dikumpulkan banyak hal yang dapat membingungkan programmer.

Penjilidan Metode Dinamis
Pengikatan dinamis memungkinkan Anda menentukan, selama eksekusi program, dan tidak selama kompilasi, metode yang harus dipanggil saat menjalankan perintah tertentu. Dalam JavaScript, mekanisme ini diterapkan menggunakan
this
dan rantai prototipe. Secara khusus, nilai spesifik
this
di dalam metode ditentukan saat runtime, dan aturan untuk menentukan nilai ini bervariasi tergantung pada bagaimana metode itu dinyatakan.
Mari kita mainkan satu game. Saya menyebutnya "Apa yang tertulis dalam ini?". Ini pilihan pertamanya - kode modul ES6:
const a = { a: 'a' }; const obj = { getThis: () => this, getThis2 () { return this; } }; obj.getThis3 = obj.getThis.bind(obj); obj.getThis4 = obj.getThis2.bind(obj); const answers = [ obj.getThis(), obj.getThis.call(a), obj.getThis2(), obj.getThis2.call(a), obj.getThis3(), obj.getThis3.call(a), obj.getThis4(), obj.getThis4.call(a) ];
Sebelum membaca lebih lanjut, pikirkan apa yang akan jatuh ke dalam susunan jawaban dan tuliskan jawabannya. Setelah Anda melakukan ini, uji diri Anda dengan
answers
larik
answers
menggunakan
console.log()
. Apakah Anda berhasil dengan benar “mendekripsi” nilai
this
di masing-masing kasus?
Kami akan menganalisis masalah ini, dimulai dengan contoh pertama.
obj.getThis()
mengembalikan
undefined
. Mengapa Fungsi panah ini tidak dapat diikat. Fungsi seperti
this
menggunakan
this
dari ruang lingkup leksikal di sekitarnya. Metode ini disebut dalam modul ES6, dalam lingkup leksikal
this
undefined
akan
undefined
. Untuk alasan yang sama,
undefined
mengembalikan panggilan ke
obj.getThis.call(a)
. Nilai
this
saat bekerja dengan fungsi panah tidak dapat ditetapkan ulang bahkan dengan
.call()
atau
.bind()
. Nilai ini akan selalu sesuai dengan
this
dari lingkup leksikal, di mana fungsi-fungsi tersebut berada.
Perintah
obj.getThis2()
menunjukkan cara bekerja dengan
this
ketika menggunakan metode objek biasa. Jika
this
tidak terikat dengan metode yang sama, dan asalkan metode ini bukan fungsi panah, yaitu, ia mendukung pengikatan
this
, kata kunci ini terikat ke objek yang metode ini disebut menggunakan sintaks mengakses properti dari objek melalui dot atau menggunakan kurung kotak.
The
obj.getThis2.call(a)
konstruk sudah agak sulit untuk
obj.getThis2.call(a)
. Metode
call()
memungkinkan Anda untuk memanggil fungsi dengan nilai yang diberikan
this
, yang ditunjukkan sebagai argumen opsional. Dengan kata lain, dalam hal ini,
this
diambil dari parameter
.call()
, sebagai hasilnya, panggilan ke
obj.getThis2.call(a)
mengembalikan objek
a
.
Menggunakan perintah
obj.getThis3 = obj.getThis.bind(obj);
kami mencoba mengikat ke metode
this
, yang merupakan fungsi panah. Seperti yang telah kita ketahui, ini tidak dapat dilakukan. Akibatnya, panggilan ke
obj.getThis3()
dan
obj.getThis3.call(a)
kembali
undefined
.
Metode yang merupakan fungsi biasa dapat dilampirkan pada
this
, jadi
obj.getThis4()
, seperti yang diharapkan, mengembalikan
obj
. Panggilan ke
obj.getThis4.call(a)
mengembalikan
obj
, dan tidak, seperti yang Anda harapkan,
a
. Faktanya adalah bahwa, sebelum memanggil perintah ini, kita sudah mengikat
this
dengan perintah
obj.getThis4 = obj.getThis2.bind(obj);
. Akibatnya, ketika mengeksekusi
obj.getThis4.call(a)
, status metode yang digunakan setelah pengikatan pertama diperhitungkan diperhitungkan.
Menggunakan ini di kelas
Ini adalah versi kedua dari gim kami - tugas yang sama, tetapi sekarang berdasarkan kelas. Di sini kita menggunakan sintaks untuk mendeklarasikan bidang kelas publik (saat ini,
proposal untuk sintaksis ini pada tahap ketiga persetujuan, tersedia secara default di Chrome, Anda dapat menggunakannya dengan
@babel/plugin-proposal-class-properties
).
class Obj { getThis = () => this getThis2 () { return this; } } const obj2 = new Obj(); obj2.getThis3 = obj2.getThis.bind(obj2); obj2.getThis4 = obj2.getThis2.bind(obj2); const answers2 = [ obj2.getThis(), obj2.getThis.call(a), obj2.getThis2(), obj2.getThis2.call(a), obj2.getThis3(), obj2.getThis3.call(a), obj2.getThis4(), obj2.getThis4.call(a) ];
Sebelum membaca lebih lanjut, pikirkan kode tersebut dan tuliskan visi Anda tentang apa yang akan jatuh ke dalam array
answers2
.
Apakah kamu sudah selesai?
Di sini, semua pemanggilan metode, kecuali untuk
obj2.getThis2.call(a)
, akan mengembalikan referensi ke instance objek. Panggilan yang sama akan mengembalikan objek
a
. Fungsi panah masih mengambil
this
dari lingkup leksikal. Perbedaan antara contoh ini dan yang sebelumnya adalah perbedaan dalam ruang lingkup dari mana
this
diambil.
Yaitu, di sini kami bekerja dengan properti kelas, yang menentukan perilaku kode ini.
Faktanya adalah bahwa selama persiapan kode untuk dieksekusi, nilai-nilai ditulis ke properti kelas seperti ini:
class Obj { constructor() { this.getThis = () => this; } ...
Dengan kata lain, ternyata fungsi panah dideklarasikan di dalam konteks fungsi konstruktor. Karena kami bekerja dengan kelas, satu-satunya cara untuk membuat instance adalah menggunakan kata kunci
new
(jika Anda lupa tentang kata kunci ini, pesan kesalahan akan ditampilkan).
Tugas paling penting yang diselesaikan oleh kata kunci
new
adalah membuat instance objek baru dan mengikatnya ke konstruktor. Fitur ini, dengan mempertimbangkan apa yang sudah kita bicarakan di bagian sebelumnya, akan membantu Anda memahami apa yang sedang terjadi.
Ringkasan
Sudahkah Anda menyelesaikan tugas yang diuraikan dalam artikel ini? Pemahaman yang baik tentang bagaimana kata kunci
this
berperilaku dalam JavaScript akan menghemat banyak waktu Anda saat debugging, ketika mencari alasan yang tidak jelas untuk kesalahan yang tidak jelas. Jika Anda menjawab beberapa pertanyaan dengan tidak tepat, itu berarti akan berguna bagi Anda untuk berlatih.
Eksperimen dengan kode sampel, lalu coba sendiri lagi, dan seterusnya, hingga Anda dapat menjawab semua pertanyaan dengan benar. Setelah Anda mengetahuinya sendiri, cari seseorang yang siap mendengarkan Anda dan katakan kepadanya mengapa metode dari tugas mengembalikan apa yang mereka kembalikan.
Jika semua ini menurut Anda lebih rumit dari yang Anda harapkan, ketahuilah bahwa Anda tidak sendirian dalam hal ini. Saya menguji beberapa pengembang untuk mengetahui fitur-fitur
this
, dan saya pikir hanya satu dari mereka yang benar-benar akurat dalam semua jawaban mereka.
Subsistem bahasa itu, yang pada awalnya tampak seperti pencarian dinamis untuk metode yang dapat dipengaruhi menggunakan
.call()
,
.bind()
atau
.apply()
, mulai terlihat jauh lebih rumit setelah kemunculan fungsi panah dan kelas.
Tampaknya, akan berguna untuk mencatat fitur utama fungsi kelas dan panah dalam hal menggunakan
this
. Ingat bahwa fungsi panah selalu menggunakan
this
dari ruang lingkup leksikal mereka, dan
this
di kelas, pada kenyataannya, terikat dengan fungsi konstruktor kelas. Dan jika Anda pernah merasa bahwa Anda tidak tahu persis apa artinya
this
, gunakan debugger untuk memeriksa asumsi Anda tentang ini.
Juga, ingatlah bahwa Anda dapat melakukan banyak hal dalam JavaScript tanpa menggunakan
this
dalam kode Anda. Pengalaman memberi tahu saya bahwa hampir semua kode JS dapat ditulis ulang dalam bentuk fungsi murni yang menerima semua argumen yang bekerja dengannya, dalam bentuk daftar parameter yang ditentukan secara eksplisit (
this
dapat diartikan sebagai parameter yang ditentukan secara implisit dengan keadaan yang bisa berubah-ubah). Logika yang terkandung dalam fungsi murni bersifat deterministik, yang meningkatkan kemampuan uji mereka. Fungsi-fungsi seperti itu tidak memiliki efek samping, yang berarti bahwa ketika bekerja dengannya, tidak seperti memanipulasi
this
, Anda tidak mungkin “menghancurkan” apa pun di luarnya. Setiap kali Anda mengubah
this
, Anda dihadapkan dengan masalah potensial, yaitu bahwa sesuatu yang bergantung pada
this
dapat berhenti bekerja dengan benar.
Meskipun demikian, perlu dicatat bahwa
this
adalah konsep yang berguna. Sebagai contoh, ini dapat diterapkan untuk mengatur pembagian metode tertentu dengan banyak objek. Bahkan dalam pemrograman fungsional,
this
bisa berguna untuk memanggil metode lain dari satu metode objek, yang memungkinkan Anda untuk membuat sesuatu yang baru berdasarkan konstruksi yang ada.

