Saya melihat yang berikut ini di sumber untuk WebKit HTML 5 SQL Storage Notes Demo :
function Note() {
var self = this;
var note = document.createElement('div');
note.className = 'note';
note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
note.addEventListener('click', function() { return self.onNoteClick() }, false);
this.note = note;
// ...
}
Penulis menggunakan diri di beberapa tempat (badan fungsi) dan ini di tempat lain (badan fungsi yang didefinisikan dalam daftar argumen metode). Apa yang sedang terjadi? Sekarang setelah saya perhatikan sekali, akankah saya mulai melihatnya di mana-mana?
javascript
scope
closures
Thomas L Holaday
sumber
sumber
this
di dalam panggilan balik?")Jawaban:
Lihat artikel ini di alistapart.com . (Ed: Artikel ini telah diperbarui sejak awalnya ditautkan)
self
sedang digunakan untuk mempertahankan referensi ke aslinyathis
bahkan ketika konteksnya sedang berubah. Ini adalah teknik yang sering digunakan dalam event handler (terutama pada penutupan).Sunting: Perhatikan bahwa menggunakan
self
sekarang tidak disarankan karenawindow.self
ada dan berpotensi menyebabkan kesalahan jika Anda tidak berhati-hati.Apa yang Anda sebut variabel tidak terlalu penting.
var that = this;
baik-baik saja, tetapi tidak ada keajaiban tentang nama itu.Fungsi yang dideklarasikan di dalam konteks (mis. Panggilan balik, penutupan) akan memiliki akses ke variabel / fungsi yang dideklarasikan dalam cakupan yang sama atau di atas.
Misalnya, panggilan balik acara sederhana:
sumber
var that = this;
Saya pikir nama variabel 'diri' tidak boleh digunakan dengan cara ini lagi, karena browser modern memberikan variabel global yang
self
menunjuk ke objek global baik dari jendela normal atau WebWorker.Untuk menghindari kebingungan dan kemungkinan konflik, Anda dapat menulis
var thiz = this
atauvar that = this
sebagai gantinya.sumber
_this
that
" (yang tidak akan pernah terbiasa dengan otak saya).self
selama Anda menyatakannya sebagaivar
iable, itu akan membayangi global. Tentu saja jika Anda lupavar
itu tidak akan bekerja dengan nama lain juga.Ya, Anda akan melihatnya di mana-mana. Itu sering
that = this;
.Lihat bagaimana
self
digunakan di dalam fungsi yang dipanggil oleh acara? Mereka akan memiliki konteks mereka sendiri, sehinggaself
digunakan untuk menampungthis
yang masukNote()
.Alasannya
self
masih tersedia untuk fungsi, meskipun mereka hanya dapat mengeksekusi setelahNote()
fungsi selesai dieksekusi, adalah bahwa fungsi dalam mendapatkan konteks fungsi luar karena penutupan .sumber
self
tidak memiliki makna khusus. Saya pribadi lebih suka menggunakan var bernama sesuatu selainself
karena sering membingungkan saya, karena saya berharap 'diri' menjadi kata yang dipesan. Jadi saya suka jawaban Anda. Dan dalam contoh OP, saya lebih sukavar thisNote = this
atau mirip.Perlu juga dicatat ada pola Proxy alternatif untuk mempertahankan referensi ke aslinya
this
dalam panggilan balik jika Anda tidak menyukaivar self = this
idiom tersebut.Karena suatu fungsi dapat dipanggil dengan konteks yang diberikan dengan menggunakan
function.apply
ataufunction.call
, Anda bisa menulis pembungkus yang mengembalikan fungsi yang memanggil fungsi Anda denganapply
ataucall
menggunakan konteks yang diberikan. Lihatproxy
fungsi jQuery untuk penerapan pola ini. Berikut ini adalah contoh menggunakannya:var wrappedFunc = $.proxy(this.myFunc, this);
wrappedFunc
kemudian dapat dipanggil dan akan memiliki versi Andathis
sebagai konteksnya.sumber
Seperti yang telah dijelaskan orang lain,
var self = this;
izinkan kode dalam penutupan untuk merujuk kembali ke lingkup induk.Namun, sekarang 2018 dan ES6 didukung secara luas oleh semua browser web utama. The
var self = this;
idiom tidak cukup penting seperti dulu.Sekarang mungkin untuk menghindari
var self = this;
melalui penggunaan fungsi panah .Dalam kasus di mana kita akan menggunakan
var self = this
:Kami sekarang dapat menggunakan fungsi panah tanpa
var self = this
:Fungsi panah tidak memiliki fungsi mereka sendiri
this
dan hanya mengasumsikan lingkup melampirkan.sumber
.addEventListender("click", (x) => { console.log(x); });
Anda telah menjelaskan caranya dan mengapa dengan sangat jelas, dan saya setuju menggunakan fungsi panah lebih masuk akal, tapi tetap saja ... ini hanya pemrograman yang mengerikan, malas, berantakan.Variabel ditangkap oleh fungsi sebaris yang ditentukan dalam metode.
this
dalam fungsi akan merujuk ke objek lain. Dengan cara ini, Anda dapat membuat fungsi menyimpan referensi kethis
dalam lingkup luar.sumber
Ini adalah kekhasan JavaScript. Ketika suatu fungsi adalah properti dari suatu objek, lebih tepat disebut metode, ini mengacu pada objek. Dalam contoh event handler, objek yang berisi adalah elemen yang memicu event. Ketika fungsi standar dipanggil, ini akan merujuk ke objek global. Ketika Anda memiliki fungsi bersarang seperti dalam contoh Anda, ini tidak berhubungan dengan konteks fungsi luar sama sekali. Fungsi dalam memang berbagi ruang lingkup dengan fungsi yang berisi, sehingga pengembang akan menggunakan variasi
var that = this
untuk mempertahankan ini yang mereka butuhkan di fungsi dalam.sumber
Sebenarnya diri adalah referensi ke jendela (
window.self
) karena itu ketika Anda mengatakanvar self = 'something'
Anda menimpa referensi jendela ke dirinya sendiri - karena diri ada di objek jendela.Inilah sebabnya mengapa sebagian besar pengembang lebih memilih
var that = this
lebihvar self = this;
Bagaimanapun;
var that = this;
tidak sejalan dengan praktik yang baik ... dengan anggapan bahwa kode Anda akan direvisi / dimodifikasi nanti oleh pengembang lain, Anda harus menggunakan standar pemrograman yang paling umum sehubungan dengan komunitas pengembangOleh karena itu Anda harus menggunakan sesuatu seperti var
oldThis
/var oThis
/ etc - untuk memperjelas ruang lingkup Anda // .. tidak terlalu banyak tetapi akan menghemat beberapa detik dan beberapa siklus otaksumber
Seperti yang disebutkan beberapa kali di atas, 'diri' hanya digunakan untuk menyimpan referensi ke 'ini' sebelum memasuki fungsi. Sekali dalam fungsi 'ini' mengacu pada sesuatu yang lain.
sumber
thisss.sayHi.call (thatt);
sumber