से डॉक्स मैं समझता हूँ कि .proxy()समारोह एक तर्क के रूप में पारित के दायरे बदल जाएगा। क्या कोई मुझे यह बेहतर समझा सकता है? हमें ऐसा क्यों करना चाहिए?
से डॉक्स मैं समझता हूँ कि .proxy()समारोह एक तर्क के रूप में पारित के दायरे बदल जाएगा। क्या कोई मुझे यह बेहतर समझा सकता है? हमें ऐसा क्यों करना चाहिए?
जवाबों:
अंततः यह क्या करता है यह सुनिश्चित करता है कि thisकिसी फ़ंक्शन का मान आपकी इच्छा का मूल्य होगा।
एक सामान्य उदाहरण setTimeoutएक clickहैंडलर के अंदर होता है ।
इसे लो:
$('#myElement').click(function() {
// In this function, "this" is our DOM element.
$(this).addClass('aNewClass');
});
इरादा काफी सरल है। जब myElementक्लिक किया जाता है, तो उसे कक्षा मिलनी चाहिए aNewClass। हैंडलर के अंदर उस thisतत्व का प्रतिनिधित्व करता है जिसे क्लिक किया गया था।
लेकिन क्या होगा अगर हम कक्षा को जोड़ने से पहले एक छोटी देरी चाहते थे? हम setTimeoutइसे पूरा करने के लिए एक का उपयोग कर सकते हैं , लेकिन परेशानी यह है कि हम जो भी फ़ंक्शन देते हैं setTimeout, thisउस फ़ंक्शन के अंदर का मूल्य windowहमारे तत्व के बजाय होगा ।
$('#myElement').click(function() {
setTimeout(function() {
// Problem! In this function "this" is not our element!
$(this).addClass('aNewClass');
}, 1000);
});
तो हम इसके बजाय क्या कर सकते हैं, इसे कॉल करना है $.proxy(), इसे फ़ंक्शन और वह मान भेजना है जिसे हम असाइन करना चाहते हैं this, और यह एक फ़ंक्शन वापस करेगा जो उस मूल्य को बनाए रखेगा।
$('#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
});
इसलिए जब हमने $.proxy()फंक्शन दिया , और जिस वैल्यू के लिए हम चाहते हैं this, उसने एक फंक्शन लौटाया जो यह सुनिश्चित करेगा कि thisठीक से सेट हो।
इसे यह कैसे करना है? यह सिर्फ एक गुमनाम फ़ंक्शन देता है जो हमारे फ़ंक्शन को विधि का उपयोग करके कॉल करता है .apply(), जो इसे स्पष्ट रूप से मान सेट करने देता है this।
लौटाए गए फ़ंक्शन पर एक सरलीकृत नज़र आ सकती है:
function() {
// v--------func is the function we gave to $.proxy
func.apply( ctx );
// ----------^------ ctx is the value we wanted for "this" (our DOM element)
}
तो यह अनाम फ़ंक्शन दिया जाता है setTimeout, और यह सब हमारे मूल फ़ंक्शन को उचित thisसंदर्भ के साथ निष्पादित करता है ।
$.proxy(function () {...}, this)इसके बजाय उपयोग करने का मूल्य क्या है (function() {...}).call(this)? क्या कोई अंतर है?
.callआप तुरंत समारोह को बुला रहे हैं। इसके साथ $.proxy, यह ऐसा है Function.prototype.bindजहां यह एक नया फ़ंक्शन देता है। उस नए फ़ंक्शन का thisमान स्थायी रूप से बाध्य होता है, ताकि जब इसे पास किया जाए setTimeoutऔर setTimeoutबाद में फ़ंक्शन को कॉल किया जाए, तब भी इसका सही thisमान होगा।
अधिक विस्तार में जाने के बिना (जो आवश्यक होगा क्योंकि यह ECMAScript में संदर्भ के बारे में है, यह संदर्भ चर आदि)
ECMA में तीन अलग-अलग प्रकार के "कॉन्टेक्ट्स" हैं- / जावास्क्रिप्ट:
प्रत्येक कोड को इसके निष्पादन के संदर्भ में निष्पादित किया जाता है । नहीं है एक वैश्विक संदर्भ और वहाँ समारोह (और eval) संदर्भों की कई उदाहरण हो सकता है। अब दिलचस्प हिस्सा:
फ़ंक्शन की प्रत्येक कॉल फ़ंक्शन निष्पादन संदर्भ में प्रवेश करती है। किसी फ़ंक्शन का निष्पादन संदर्भ इस तरह दिखता है:
सक्रियण ऑब्जेक्ट
स्कोप चेन
इस मान को
तो यह मान एक विशेष वस्तु है जो निष्पादन के संदर्भ से संबंधित है। ECMA- / जावास्क्रिप्ट में दो फ़ंक्शन हैं जो फ़ंक्शन मान के संदर्भ में इस मान को बदल सकते हैं :
.call()
.apply()
यदि हमारे पास कोई फ़ंक्शन है foobar()तो हम कॉल करके इस मान को बदल सकते हैं :
foobar.call({test: 5});
अब हम foobarउस वस्तु में पहुँच सकते हैं जिसे हमने पास किया था:
function foobar() {
this.test // === 5
}
वास्तव में यही jQuery.proxy()होता है। यह एक (और एक वस्तु के अलावा और कुछ भी नहीं है) लेता है functionऔर contextफ़ंक्शन को लिंक करके .call()या .apply()उस नए फ़ंक्शन को देता है।
एक ही लक्ष्य "तत्काल-इनवॉइस फंक्शन एक्सप्रेशन, शॉर्ट: IIFE" स्व निष्पादित कार्य का उपयोग करके प्राप्त किया जा सकता है :
$('#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>