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 thisdalam suatu fungsi akan menjadi nilai yang Anda inginkan.
Contoh umum adalah dalam setTimeoutyang terjadi di dalam clickpawang.
Ambil ini:
$('#myElement').click(function() {
// In this function, "this" is our DOM element.
$(this).addClass('aNewClass');
});
Niatnya cukup sederhana. Ketika myElementdiklik, itu harus mendapatkan kelas aNewClass. Di dalam pawang thismewakili elemen yang diklik.
Tetapi bagaimana jika kita ingin penundaan singkat sebelum menambahkan kelas? Kita mungkin menggunakan a setTimeoutuntuk mencapainya, tetapi masalahnya adalah bahwa fungsi apa pun yang kita berikan setTimeout, nilai thisdi dalam fungsi itu akan windowbukan 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 thisdiatur 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 thiskonteks yang tepat .
$.proxy(function () {...}, this)daripada (function() {...}).call(this)? Apakah ada perbedaan?
.callAnda memanggil fungsi segera. Dengan $.proxy, itu seperti di Function.prototype.bindmana ia mengembalikan fungsi baru. Fungsi baru itu memiliki thisnilai yang terikat secara permanen, sehingga ketika diteruskan ke setTimeout, dan setTimeoutmemanggil 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 foobarobjek yang kita lewati:
function foobar() {
this.test // === 5
}
Inilah tepatnya yang jQuery.proxy()dilakukannya. Dibutuhkan a functiondan 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>