Dari dokumen saya mengerti bahwa .proxy()
akan mengubah ruang lingkup fungsi yang dilewatkan sebagai argumen. Bisakah seseorang tolong jelaskan saya ini lebih baik? Kenapa kita harus melakukan ini?
Dari dokumen saya mengerti bahwa .proxy()
akan mengubah ruang lingkup fungsi yang dilewatkan sebagai argumen. Bisakah seseorang tolong jelaskan saya ini lebih baik? Kenapa kita harus melakukan ini?
Jawaban:
Apa yang akhirnya dilakukan adalah memastikan bahwa nilai this
dalam suatu fungsi akan menjadi nilai yang Anda inginkan.
Contoh umum adalah dalam setTimeout
yang terjadi di dalam click
pawang.
Ambil ini:
$('#myElement').click(function() {
// In this function, "this" is our DOM element.
$(this).addClass('aNewClass');
});
Niatnya cukup sederhana. Ketika myElement
diklik, itu harus mendapatkan kelas aNewClass
. Di dalam pawang this
mewakili elemen yang diklik.
Tetapi bagaimana jika kita ingin penundaan singkat sebelum menambahkan kelas? Kita mungkin menggunakan a setTimeout
untuk mencapainya, tetapi masalahnya adalah bahwa fungsi apa pun yang kita berikan setTimeout
, nilai this
di dalam fungsi itu akan window
bukan elemen kita.
$('#myElement').click(function() {
setTimeout(function() {
// Problem! In this function "this" is not our element!
$(this).addClass('aNewClass');
}, 1000);
});
Jadi yang bisa kita lakukan sebagai gantinya adalah memanggil $.proxy()
, mengirimkannya fungsi dan nilai yang ingin kita tetapkan this
, dan itu akan mengembalikan fungsi yang akan mempertahankan nilai itu.
$('#myElement').click(function() {
// ------------------v--------give $.proxy our function,
setTimeout($.proxy(function() {
$(this).addClass('aNewClass'); // Now "this" is again our element
}, this), 1000);
// ---^--------------and tell it that we want our DOM element to be the
// value of "this" in the function
});
Jadi setelah kami memberikan $.proxy()
fungsi, dan nilai yang kami inginkan this
, mengembalikan fungsi yang akan memastikan bahwa this
diatur dengan benar.
Bagaimana cara melakukannya? Itu hanya mengembalikan fungsi anonim yang memanggil fungsi kami menggunakan .apply()
metode, yang memungkinkannya secara eksplisit mengatur nilai this
.
Tampilan yang disederhanakan pada fungsi yang dikembalikan mungkin terlihat seperti:
function() {
// v--------func is the function we gave to $.proxy
func.apply( ctx );
// ----------^------ ctx is the value we wanted for "this" (our DOM element)
}
Jadi fungsi anonim ini diberikan setTimeout
, dan semua yang dilakukannya adalah menjalankan fungsi asli kami dengan this
konteks yang tepat .
$.proxy(function () {...}, this)
daripada (function() {...}).call(this)
? Apakah ada perbedaan?
.call
Anda memanggil fungsi segera. Dengan $.proxy
, itu seperti di Function.prototype.bind
mana ia mengembalikan fungsi baru. Fungsi baru itu memiliki this
nilai yang terikat secara permanen, sehingga ketika diteruskan ke setTimeout
, dan setTimeout
memanggil fungsi nanti, ia akan tetap memiliki nilai yang benar this
.
Tanpa masuk ke detail yang lebih besar (yang diperlukan karena ini adalah tentang Konteks dalam ECMAScript, variabel konteks ini, dll.)
Ada tiga jenis "Konteks" dalam ECMA- / Javascript:
Setiap kode dieksekusi dalam konteks eksekusi . Ada satu konteks global dan ada banyak contoh konteks fungsi (dan eval). Sekarang bagian yang menarik:
Setiap panggilan fungsi masuk ke konteks eksekusi fungsi. Konteks eksekusi dari suatu fungsi terlihat seperti:
Aktivasi Obyek
Lingkup Rantai
nilai ini
Jadi nilai ini adalah objek khusus yang terkait dengan konteks eksekusi. Ada dua fungsi dalam ECMA- / Javascript yang dapat mengubah nilai ini dalam konteks eksekusi fungsi:
.call()
.apply()
Jika kami memiliki fungsi, foobar()
kami dapat mengubah nilai ini dengan memanggil:
foobar.call({test: 5});
Sekarang kita bisa mengakses foobar
objek yang kita lewati:
function foobar() {
this.test // === 5
}
Inilah tepatnya yang jQuery.proxy()
dilakukannya. Dibutuhkan a function
dan context
(yang tidak lain adalah objek) dan menautkan fungsi dengan memanggil .call()
atau .apply()
mengembalikan fungsi baru tersebut.
Tujuan yang sama dapat dicapai dengan menggunakan "Segera-dipanggil Fungsi Ekspresi, singkat: Iife" fungsi mengeksekusi diri :
$('#myElement').click(function() {
(function(el){
setTimeout(function() {
// Problem! In this function "this" is not our element!
el.addClass('colorme');
}, 1000);
})($(this)); // self executing function
});
.colorme{
color:red;
font-size:20px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<div id="myElement">Click me</div>
</body>
</html>