Dalam blog ini, kami akan menyelami kata kunci "ini" dalam JavaScript, meneroka cara ia berfungsi, sebab ia berkelakuan berbeza dalam pelbagai konteks dan cara menguasainya boleh menjadikan kod anda lebih bersih dan cekap. Pada akhirnya, anda akan mempunyai pemahaman yang kukuh tentang cara menggunakan kata kunci "ini" dengan berkesan dalam JavaScript untuk projek anda.
Kata kunci "ini" dalam JavaScript adalah penting kerana ia mendayakan interaksi dinamik dan berasaskan konteks dalam kod anda. Berikut ialah beberapa sebab mengapa ia sangat berharga:
Dengan ciri ini, "ini" bukan sahaja kata kunci tetapi juga aspek asas pendekatan JavaScript terhadap fungsi, objek dan pengekodan terdorong konteks.
Dalam JavaScript, nilai kata kunci "ini" tidak tetap dan boleh berbeza-beza bergantung pada konteks di mana fungsi dipanggil. Sifat dinamik "ini" ini ialah salah satu aspek JavaScript yang paling unik—dan kadangkala mengelirukan. Secara umumnya, terdapat beberapa konteks yang menentukan nilai "ini".
Mari kita pecahkan setiap konteks dengan contoh untuk melihat bagaimana "ini" berkelakuan:
Apabila "ini" digunakan dalam konteks global atau dalam fungsi kendiri, ia merujuk kepada objek global, iaitu tetingkap dalam penyemak imbas dan global dalam Node.js.
Contoh:
function showGlobalContext() { console.log(this); } showGlobalContext();
Kod ini mengeluarkan Tetingkap { ... } dalam penyemak imbas atau [objek global] dalam Node.js. Memandangkan showGlobalContext dipanggil dalam konteks global, "ini" menghala ke objek global (tetingkap dalam penyemak imbas atau global dalam Node.js). Di sini, tiada pengikatan yang jelas atau tersirat, jadi "ini" menjadi lalai kepada skop global.
Apabila fungsi dipanggil sebagai kaedah objek, "ini" merujuk kepada objek yang dipanggil kaedah. Ini dikenali sebagai pengikatan tersirat.
Contoh:
const person = { name: "Alice", greet() { console.log(`Hello, I am ${this.name}`); } }; person.greet();
Ini menghasilkan Hello, saya Alice kerana salam dipanggil oleh objek orang. Disebabkan pengikatan tersirat, salam dalam "ini" merujuk kepada orang, membenarkan akses kepada sifat namanya. Pengikatan tersirat berlaku apabila fungsi dipanggil dengan objek sebelumnya.
JavaScript membenarkan pengikatan eksplisit "ini" menggunakan kaedah panggilan, gunakan dan ikat. Kaedah ini membolehkan anda menetapkan "ini" terus kepada objek tertentu.
Contoh:
function introduce() { console.log(`Hello, I am ${this.name}`); } const user = { name: "Bob" }; // Using call introduce.call(user); // Using apply introduce.apply(user); // Using bind const boundIntroduce = introduce.bind(user); boundIntroduce();
Setiap kaedah invocation output Hello, saya Bob. Dengan memanggil dan memohon, kami segera memanggil memperkenalkan, secara eksplisit menetapkan "ini" kepada pengguna, yang mempunyai sifat nama "Bob." Kaedah bind, bagaimanapun, mengembalikan fungsi baharu dengan "ini" terikat secara kekal kepada pengguna, membenarkan boundIntroduce dipanggil kemudian dengan "ini" masih ditetapkan kepada pengguna.
Fungsi anak panah dalam JavaScript tidak mempunyai pengikatan "ini" sendiri. Sebaliknya, mereka mewarisi "ini" daripada skop leksikal mereka, atau konteks di mana ia ditakrifkan. Tingkah laku ini berguna untuk panggilan balik dan fungsi bersarang.
Contoh:
const team = { name: "Development Team", members: ["Alice", "Bob", "Charlie"], introduceTeam() { this.members.forEach(member => { console.log(`${member} is part of ${this.name}`); }); } }; team.introduceTeam();
Ini menghasilkan:
Alice is part of Development Team Bob is part of Development Team Charlie is part of Development Team
Di sini, fungsi anak panah di dalam forEach tidak mencipta "ini" sendiri; sebaliknya, ia mewarisi "ini" daripada introduceTeam, yang dipanggil oleh pasukan. Akibatnya, "ini" di dalam fungsi anak panah merujuk kepada pasukan, membenarkan akses kepada sifat nama. Jika fungsi biasa digunakan dalam forEach, "ini" sama ada tidak ditentukan (dalam mod ketat) atau menghala ke objek global, yang membawa kepada hasil yang tidak dijangka.
Apabila fungsi digunakan sebagai pembina (dipanggil dengan kata kunci baharu), "ini" di dalam fungsi itu merujuk kepada contoh yang baru dibuat. Ini berguna untuk mencipta berbilang tika objek dengan sifat dan kaedahnya sendiri.
Contoh:
function showGlobalContext() { console.log(this); } showGlobalContext();
Dalam contoh ini, memanggil Orang baharu("Alice") mencipta objek baharu dengan "ini" merujuk kepada objek baharu itu, bukan konteks global atau mana-mana konteks lain. Hasilnya ialah tika baharu (person1) dengan sifat nama ditetapkan kepada "Alice."
Dalam sintaks ES6, kelas JavaScript juga menggunakan kata kunci "ini" untuk merujuk kepada contoh kelas dalam kaedah. Tingkah laku ini serupa dengan pengikatan baharu, kerana setiap tika kelas akan mempunyai konteks "ini" sendiri.
Contoh:
const person = { name: "Alice", greet() { console.log(`Hello, I am ${this.name}`); } }; person.greet();
Di sini, "ini" dalam showModel merujuk kepada contoh khusus myCar, memberikan akses kepada sifat modelnya. Setiap kejadian yang dibuat dengan Carwill baharu mempunyai "ini" sendiri merujuk kepada kejadian itu.
Dalam pendengar acara, "ini" merujuk kepada elemen HTML yang mencetuskan acara. Ini memudahkan untuk mengakses sifat atau kaedah elemen itu tanpa perlu menyampaikannya secara eksplisit sebagai hujah.
Contoh:
function introduce() { console.log(`Hello, I am ${this.name}`); } const user = { name: "Bob" }; // Using call introduce.call(user); // Using apply introduce.apply(user); // Using bind const boundIntroduce = introduce.bind(user); boundIntroduce();
Dalam kes ini, "ini" di dalam pendengar acara merujuk kepada elemen butang yang telah diklik, membenarkan akses kepada sifat dan kaedahnya. Walau bagaimanapun, jika anda menggunakan fungsi anak panah sebagai pengendali acara, "ini" akan merujuk kepada skop leksikal, mungkin mengakibatkan tingkah laku yang tidak dijangka.
Salah faham tentang "ini" boleh membawa kepada hasil yang tidak dijangka dalam JavaScript. Berikut ialah beberapa perangkap biasa yang perlu diberi perhatian:
Apabila menghantar kaedah sebagai panggilan balik, "ini" boleh kehilangan rujukan asalnya. Ini berlaku kerana apabila fungsi dipanggil sebagai kendiri (tanpa objek memanggilnya), "ini" menjadi lalai kepada objek global atau menjadi tidak ditentukan dalam mod ketat.
Contoh:
const team = { name: "Development Team", members: ["Alice", "Bob", "Charlie"], introduceTeam() { this.members.forEach(member => { console.log(`${member} is part of ${this.name}`); }); } }; team.introduceTeam();
Dalam contoh ini, ini menjadi tidak ditentukan dalam ucapan kerana panggilan setTimeout memberi salam sebagai fungsi kendiri, bukan sebagai kaedah pengguna.
Fungsi anak panah tidak mempunyai konteks "ini" sendiri; sebaliknya, mereka mewarisi "ini" daripada skop leksikal sekeliling. Ini boleh menyebabkan masalah apabila fungsi anak panah digunakan dalam situasi di mana "ini" harus merujuk kepada objek panggilan, seperti dalam kaedah atau pendengar acara. Tingkah laku ini boleh membawa kepada nilai yang tidak dijangka untuk "ini" dalam senario di mana pembangun mungkin mengharapkan konteks "ini" baharu.
Contoh:
Alice is part of Development Team Bob is part of Development Team Charlie is part of Development Team
Di sini, "ini" merujuk kepada objek global dan bukannya butang kerana fungsi anak panah mewarisi "ini" daripada skop penentunya, bukannya daripada konteks peristiwa.
Apabila menggunakan fungsi biasa yang bersarang dalam kaedah, "ini" mungkin secara tidak dijangka menghala ke objek global dan bukannya fungsi atau objek luar. Ini berlaku kerana setiap panggilan fungsi mempunyai konteks "ini" sendiri. Dalam fungsi bersarang, jika "ini" tidak terikat secara eksplisit, fungsi lalai kembali kepada konteks global, yang boleh membawa kepada tingkah laku yang tidak dijangka apabila cuba mengakses sifat objek luar.
Contoh:
function showGlobalContext() { console.log(this); } showGlobalContext();
Dalam contoh ini, "ini" dalam showName lalai kepada skop global dan bukannya merujuk kepada orang, yang membawa kepada output yang tidak dijangka.
Menguasai kata kunci "ini" dalam JavaScript boleh meningkatkan kebolehbacaan dan kebolehselenggaraan kod. Berikut ialah beberapa amalan terbaik untuk membantu memastikan "ini" berkelakuan seperti yang diharapkan dalam pelbagai konteks:
Untuk fungsi yang perlu mengekalkan "ini" dari skop sekeliling, gunakan fungsi anak panah. Fungsi anak panah tidak mempunyai "ini" sendiri, jadi mereka mewarisinya dari tempat ia ditakrifkan. Ini berguna dalam panggilan balik atau fungsi bersarang.
Contoh:
const person = { name: "Alice", greet() { console.log(`Hello, I am ${this.name}`); } }; person.greet();
Apabila anda perlu menetapkan "ini" pada objek tertentu, gunakan bind, panggil atau gunakan. Ini berguna untuk panggilan balik atau panggilan fungsi kendiri yang anda mahu "ini" merujuk objek tertentu.
Contoh:
function introduce() { console.log(`Hello, I am ${this.name}`); } const user = { name: "Bob" }; // Using call introduce.call(user); // Using apply introduce.apply(user); // Using bind const boundIntroduce = introduce.bind(user); boundIntroduce();
Dalam skop global, "ini" merujuk kepada tetingkap (dalam penyemak imbas) atau objek global (dalam Node.js), yang boleh membawa kepada hasil yang tidak dijangka. Simpan fungsi yang bergantung kepada "ini" dalam objek atau kelas.
Contoh:
const team = { name: "Development Team", members: ["Alice", "Bob", "Charlie"], introduceTeam() { this.members.forEach(member => { console.log(`${member} is part of ${this.name}`); }); } }; team.introduceTeam();
Dalam kelas ES6 atau fungsi pembina, gunakan "ini" sebagai contoh sifat. Ini memastikan data setiap kejadian berasingan, mengikut reka bentuk berorientasikan objek.
Contoh:
Alice is part of Development Team Bob is part of Development Team Charlie is part of Development Team
Uji cara "ini" berkelakuan apabila fungsi anda digunakan dalam konteks yang berbeza—seperti kaedah, panggil balik dan pendengar acara. Ini membantu menangkap hasil yang tidak dijangka pada awal pembangunan.
Dalam blog ini, kami telah meneroka kata kunci "ini" dalam JavaScript, merangkumi gelagatnya dalam pelbagai konteks seperti fungsi global, tersirat, eksplisit, pengikatan baharu dan anak panah. Kami juga membincangkan perangkap biasa yang perlu dielakkan dan amalan terbaik untuk memastikan "ini" berfungsi seperti yang diharapkan dalam kod anda. Menguasai "ini" boleh meningkatkan kejelasan dan fleksibiliti kod dengan sangat baik, memperkasakan anda untuk menulis JavaScript yang lebih cekap dan boleh diselenggara.
Untuk penerokaan yang lebih mendalam, sila semak dokumentasi MDN tentang kata kunci "ini" dalam JavaScript.
Atas ialah kandungan terperinci Kata Kunci this' dalam JavaScript: Panduan Pemula. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!