Saya punya pertanyaan tentang bagaimana pointer "ini" diperlakukan dalam skenario fungsi bersarang.
Katakanlah saya memasukkan kode contoh berikut ini ke dalam halaman web. Saya mendapatkan pesan kesalahan saat memanggil fungsi bersarang "doSomeEffects ()". Saya memeriksa di Firebug dan ini menunjukkan bahwa ketika saya berada dalam fungsi bersarang itu, penunjuk "ini" sebenarnya menunjuk ke objek "jendela" global - yang tidak saya duga. Saya tidak harus memahami sesuatu dengan benar karena saya pikir karena saya mendeklarasikan fungsi bersarang dalam fungsi objek, itu harus memiliki ruang lingkup "lokal" dalam hubungannya dengan fungsi (yaitu, penunjuk "ini" akan merujuk ke objek itu sendiri seperti bagaimana di pernyataan "jika" pertama saya).
Setiap petunjuk (tidak ada permainan kata-kata) akan dihargai.
var std_obj = {
options : { rows: 0, cols: 0 },
activeEffect : "none",
displayMe : function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect=="fade") { }
var doSomeEffects = function() {
// the 'this' pointer is referring to the window obj, why?
if (this.activeEffect=="fade") { }
}
doSomeEffects();
}
};
std_obj.displayMe();
sumber
this
mengacu pada objek tempat fungsi tersebut dipanggil.var self = this;
dan kemudian merujuk keself
fungsi dalam melalui closure.doSomeEffects
tidak terkait dengan objek apa pun secara khusus, sehinggathis
diasumsikan sebagai jendela, induk dari semua elemen.Jawaban:
Dalam JavaScript,
this
objek benar-benar didasarkan pada cara Anda membuat panggilan fungsi.Secara umum ada tiga cara untuk mengatur
this
objek:someThing.someFunction(arg1, arg2, argN)
someFunction.call(someThing, arg1, arg2, argN)
someFunction.apply(someThing, [arg1, arg2, argN])
Dalam semua contoh di atas,
this
objek akan menjadisomeThing
. Memanggil fungsi tanpa objek induk terkemuka biasanya akan memberi Anda objek global yang di sebagian besar browser berartiwindow
objek tersebut.sumber
this.doSomeEffects();
berdasarkan jawaban Anda tetapi tetap saja tidak berhasil. Mengapa?this
dalamthis.doSomeEffects()
menunjuk kestd_obj
. Seperti yang dijelaskan pada jawaban di atas jika suatu fungsi tidak memiliki referensi objek maka itu diperlukanthis
untuk menjadi objek jendela.Karena ini tampaknya menjadi salah satu pertanyaan yang paling disukai dari jenisnya, izinkan saya menambahkan, setelah bertahun-tahun ini, solusi ES6 menggunakan fungsi panah:
sumber
this
bukan bagian dari lingkup closure, itu bisa dianggap sebagai parameter tambahan untuk fungsi yang terikat di situs panggilan. Jika metode tidak dipanggil sebagai metode maka objek global akan diteruskan sebagaithis
. Di browser, objek global identik denganwindow
. Misalnya, perhatikan fungsi berikut,dan objek berikut,
Jika Anda memanggil fungsi menggunakan sintaks metode seperti,
kemudian
this
terikatobj
.Jika Anda memanggil someFunction () secara langsung, seperti,
kemudian
this
terikat ke objek global, yaituwindow
.Penyelesaian yang paling umum adalah menangkap ini ke dalam closure seperti,
sumber
Ada perbedaan antara variabel enklosur dan "ini". "ini" sebenarnya ditentukan oleh pemanggil fungsi, sementara variabel eksplisit tetap utuh di dalam blok deklarasi fungsi yang dikenal sebagai enklosur. Lihat contoh di bawah ini:
Anda dapat mencobanya di sini: http://jsfiddle.net/kSTBy/
Apa yang terjadi dalam fungsi Anda adalah "doSomeEffects ()", dipanggil secara eksplisit, ini berarti konteks atau fungsi "ini" adalah jendela. jika "doSomeEffects" adalah metode prototipe misalnya this.doSomeEffects pada kata "myObject", maka myObject.doSomeEffects () akan menyebabkan "ini" menjadi "myObject".
sumber
_this.name = myFirstObject this.name = mySecondObject
Untuk memahami pertanyaan ini, coba dapatkan keluaran untuk cuplikan berikut
Kode di atas akan menampilkan yang berikut ke konsol:
Di fungsi luar, baik this maupun self merujuk ke myObject dan oleh karena itu keduanya dapat mereferensikan dan mengakses foo dengan benar.
Namun, dalam fungsi bagian dalam, ini tidak lagi mengacu pada myObject. Akibatnya, this.foo tidak terdefinisi di fungsi dalam, sedangkan referensi ke variabel lokal itu sendiri tetap dalam cakupan dan dapat diakses di sana. (Sebelum ECMA 5, ini di fungsi bagian dalam akan merujuk ke objek jendela global; sedangkan, pada ECMA 5, ini di fungsi bagian dalam tidak akan ditentukan.)
sumber
this
mengacu pada objek jendela (dalam lingkungan browser) atau objek GLOBAL (dalam lingkungan node.js)this
tidak lagi mengacu pada jendelaSeperti yang dijelaskan oleh Kyle, Anda dapat menggunakan
call
atauapply
menentukanthis
di dalam fungsi:Inilah konsep yang diterapkan pada kode Anda:
JsFiddle
sumber
Saya juga mendapat peringatan " Akses referensi yang berpotensi tidak valid ke bidang kelas melalui ini "
sumber
Karena tidak disebutkan, saya akan menyebutkan bahwa menggunakan
.bind()
adalah solusi -Berikut adalah contoh yang lebih sederhana -
Memang benar bahwa menggunakan fungsi panah
=>
terlihat lebih licin dan mudah bagi programmer. Namun, harus diingat bahwa ruang lingkup leksikal mungkin memerlukan lebih banyak pekerjaan dalam hal pemrosesan dan memori untuk menyiapkan dan mempertahankan ruang lingkup leksikal tersebut, dibandingkan dengan sekadar mengaitkan fungsithis
dengan penunjuk melalui.bind()
.Bagian dari manfaat pengembangan kelas di JS adalah menyediakan metode untuk membuat
this
lebih andal hadir dan tersedia, untuk menjauh dari pemrograman fungsional dan cakupan leksikal, dan dengan demikian mengurangi overhead.Dari MDN
sumber