$ .Proxy () को jQuery में समझना


167

से डॉक्स मैं समझता हूँ कि .proxy()समारोह एक तर्क के रूप में पारित के दायरे बदल जाएगा। क्या कोई मुझे यह बेहतर समझा सकता है? हमें ऐसा क्यों करना चाहिए?


1
प्रलेखन के अनुसार, "यह विधि ईवेंट हैंडलर को एक तत्व में संलग्न करने के लिए सबसे उपयोगी है जहां संदर्भ एक अलग ऑब्जेक्ट पर वापस इंगित कर रहा है। इसके अतिरिक्त, jQuery सुनिश्चित करता है कि भले ही आप फ़ंक्शन को बाइंड करें jQuery.proxy () से लौटा हो। अभी भी सही फ़ंक्शन को अनबाइंड करें, यदि मूल पास हो "। वहाँ कुछ विशेष के बारे में है कि phrasing तुम कमी मिल रहा है?
bzlm

1
यह यहां इसके अतिरिक्त स्पष्ट नहीं है, jQuery सुनिश्चित करती है कि भले ही आप बाँध समारोह jQuery.proxy (से लौटे) यह अभी भी अनबाइंड सही समारोह, यदि मूल ".क्या के मूल अर्थ को पारित कर दिया?
आदित्य शुक्ला

मूल वह है जिसके लिए एक प्रॉक्सी बनाया गया था। लेकिन जब से आप इस सामान को पूरी तरह से समझ नहीं पा रहे हैं, क्या आप सुनिश्चित हैं कि आपको इसका उपयोग करने की आवश्यकता है?
bzlm

1
नेटवर्ट्स द्वारा एक शानदार वीडियो ट्यूटोरियल दिखाया गया है कि $ .proxy कैसे काम करता है। http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-learning-jquery-1-4s-proxy/
हुसैन

1
@bzlm, मैं jquery प्रलेखन पढ़ रहा था जब मैं इस पद्धति पर आया था।
आदित्य शुक्ला

जवाबों:


381

अंततः यह क्या करता है यह सुनिश्चित करता है कि 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)? क्या कोई अंतर है?
जस्टिन मॉर्गन

11
@JustinMorgan: .callआप तुरंत समारोह को बुला रहे हैं। इसके साथ $.proxy, यह ऐसा है Function.prototype.bindजहां यह एक नया फ़ंक्शन देता है। उस नए फ़ंक्शन का thisमान स्थायी रूप से बाध्य होता है, ताकि जब इसे पास किया जाए setTimeoutऔर setTimeoutबाद में फ़ंक्शन को कॉल किया जाए, तब भी इसका सही thisमान होगा।
ग्रे स्टेट

2
इस तकनीक का फायदा क्या है, यदि कोई है, तो इस तरह से? $ ('# myElement'); क्लिक करें (फ़ंक्शन () {var el = $ (this); setTimeout (फ़ंक्शन () {el.addClass ('aNewClass');}; 1000);});
ग्रेग

1
आपको इस उदाहरण के लिए $ .proxy मेथड का उपयोग करने की आवश्यकता नहीं है। इसके बजाय आप इसे केवल इस $ ('# myElement') की तरह फिर से लिख सकते हैं। क्लिक करें (फ़ंक्शन () {var that = this; setTimeout (फ़ंक्शन () / a) हैंडलर विधि $ (कि) .addClass ('aNewass');}; 1000);}) के दायरे में घोषित एक चर के माध्यम से / नया संदर्भ;
पौल

4
112k प्रतिनिधि, डरावना-अच्छा जावास्क्रिप्ट / jQuery ज्ञान के साथ एक अनाम उपयोगकर्ता, और अक्टूबर 2011 के बाद से नहीं देखा गया है ... जॉन Resig शायद?
कैंटर

49

अधिक विस्तार में जाने के बिना (जो आवश्यक होगा क्योंकि यह ECMAScript में संदर्भ के बारे में है, यह संदर्भ चर आदि)

ECMA में तीन अलग-अलग प्रकार के "कॉन्टेक्ट्स" हैं- / जावास्क्रिप्ट:

  • वैश्विक संदर्भ
  • क्रिया प्रसंग
  • स्पष्ट संदर्भ

प्रत्येक कोड को इसके निष्पादन के संदर्भ में निष्पादित किया जाता है । नहीं है एक वैश्विक संदर्भ और वहाँ समारोह (और eval) संदर्भों की कई उदाहरण हो सकता है। अब दिलचस्प हिस्सा:

फ़ंक्शन की प्रत्येक कॉल फ़ंक्शन निष्पादन संदर्भ में प्रवेश करती है। किसी फ़ंक्शन का निष्पादन संदर्भ इस तरह दिखता है:

सक्रियण ऑब्जेक्ट
स्कोप चेन
इस मान को

तो यह मान एक विशेष वस्तु है जो निष्पादन के संदर्भ से संबंधित है। ECMA- / जावास्क्रिप्ट में दो फ़ंक्शन हैं जो फ़ंक्शन मान के संदर्भ में इस मान को बदल सकते हैं :

.call()
.apply()

यदि हमारे पास कोई फ़ंक्शन है foobar()तो हम कॉल करके इस मान को बदल सकते हैं :

foobar.call({test: 5});

अब हम foobarउस वस्तु में पहुँच सकते हैं जिसे हमने पास किया था:

function foobar() { 
    this.test // === 5
}

वास्तव में यही jQuery.proxy()होता है। यह एक (और एक वस्तु के अलावा और कुछ भी नहीं है) लेता है functionऔर contextफ़ंक्शन को लिंक करके .call()या .apply()उस नए फ़ंक्शन को देता है।


1
उत्कृष्ट स्पष्टीकरण, फ़ंक्शन के लिए आधिकारिक jQuery डॉक्स की तुलना में सरल / बेहतर
higuaro

4

मैंने यह फ़ंक्शन लिखा है:

function my_proxy (func,obj)
{
    if (typeof(func)!="function")
        return;

    // If obj is empty or another set another object 
    if (!obj) obj=this;

    return function () { return func.apply(obj,arguments); }
}

1

एक ही लक्ष्य "तत्काल-इनवॉइस फंक्शन एक्सप्रेशन, शॉर्ट: 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>


2
जिसे आमतौर पर "सेल्फ एक्ज़ीक्यूटिव फंक्शन एक्सप्रेशन" (IIFE) के बजाय "सेल्फ एक्ज़ीक्यूटिंग फंक्शन" कहा जाता है, en.wikipedia.org/wiki/Immediately-invoked_function_expression देखें ।
क्रिस बीज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.