2011-09-18 20 views
15

मैं JavaScript Garden के माध्यम से ब्राउज़ कर रहा था जब मैंने Function.call.apply हैक पर ठोकर खाई जिसका उपयोग "तेज़, अनबाउंड रैपर" बनाने के लिए किया जाता है। इसे कहते हैं:जावास्क्रिप्ट में Function.call.apply का उपयोग करने का क्या उद्देश्य है?

एक और चाल दोनों कॉल का उपयोग करें और तेजी से, अबाध रैपर बनाने के लिए एक साथ लागू करने के लिए है।

function Foo() {} 

Foo.prototype.method = function(a, b, c) { 
    console.log(this, a, b, c); 
}; 

// Create an unbound version of "method" 
// It takes the parameters: this, arg1, arg2...argN 
Foo.method = function() { 

    // Result: Foo.prototype.method.call(this, arg1, arg2... argN) 
    Function.call.apply(Foo.prototype.method, arguments); 
}; 

क्या मुझे समझ नहीं आता क्यों Function.call.apply का उपयोग करते समय Function.apply पर्याप्त होगा परेशान है। आखिरकार, वे दोनों अर्थात् समकक्ष हैं।

+0

मैंने [जावास्क्रिप्ट गार्डन] (http://javascriptgarden.info/) के लिए एक लिंक पोस्ट किया था। यदि आप सीधे उस अनुभाग में कूदना चाहते हैं जिसमें पोस्ट है, तो [यहां] क्लिक करें (http://javascriptgarden.info/#function.arguments)। –

+0

tnx, - ऐसा लगता है कि वे इस हैक को कुछ गति देता है .. लेकिन, वास्तव में, बस ** इसका उपयोग न करें **। – c69

+2

@Aadit 'Function.call.apply' और 'फ़ंक्शन।लागू करें 'यहां वही नहीं हो सकता है क्योंकि पूर्व' फंक्शनक्शन 'लागू होता है जबकि दूसरा' फंक्शन 'कन्स्ट्रक्टर को लागू करने का प्रयास करता है। मेरे जवाब में विवरण, लेकिन अगर मैं इवो वेटज़ेल इस जवाब देने के लिए आया तो मैं शर्त लगाऊंगा कि वह कहीं अधिक स्पष्ट और समझदार होगा। यह बल्कि गहरी चीजें है। मैं मानता हूं कि शायद ऐसा कुछ नहीं है जिसे आप तब तक उपयोग नहीं करना चाहिए जब तक कि आप सहकर्मियों को खर्च नहीं करना चाहते हैं, ओह मुझे नहीं पता, एक आधे घंटे_ इसे समझने की कोशिश कर रहा है। :) –

उत्तर

13

नहीं है, Function.call.apply और Function.apply में ही नहीं हैं ये मामला।

चलो कहते हैं कि मूल फोन करने वाले

Foo.method(t, x, y, z) 

आह्वान कॉल के साथ और जावास्क्रिप्ट गार्डन कोड के रूप में, एक साथ लागू करते हैं। यह

Function.call.apply(Foo.prototype.method, arguments); 

निष्पादित करता है जो (शिथिल, सरणी-अंकन में arguments लेखन) है:

Function.call.apply(Foo.prototype.method, [t, x, y, z]); 

जो invokes Function.callthis==Foo.prototype.method साथ:

Foo.prototype.method.call(t, x, y, z) 

जो t करने के लिए Foo.prototype.method साथ this सेट कॉल और तर्क x, y, और z। मिठाई। टिप्पणियों की तरह ही। हमने सफलतापूर्वक एक रैपर बनाया है।

अब मान लीजिए कि आपने के बजाय Function.apply कहा है, जिसका आप दावा करते हैं कि यह अर्थात् समकक्ष है। आप जो (शिथिल)

Function.apply(Foo.prototype.method, [t, x, y, z]); 

जो करने के लिए Foo.prototype.method और तर्क t, x, y, और zthis सेट के साथ समारोह Function (ओह!) कहता है

Function.apply(Foo.prototype.method, arguments); 

होगा।

बिलकुल भी नहीं।

+0

लेकिन इस तरह के लपेटने का उद्देश्य क्या है? – c69

+3

इसका उद्देश्य 'Foo.prototype.method' को कॉल करना है, बिना इसे 'Foo' के उदाहरण के बाध्य किए। इसके बजाय आप 'अपने' मूल्य को 'Foo.prototype.method' के भीतर' this' के मान के रूप में उपयोग करने के लिए पास करते हैं। आप ऐसा क्यों करेंगे? हो सकता है कि आप कुछ कार्यात्मक प्रोग्रामिंग करना चाहते हैं और जिस फ़ंक्शन को आप मानचित्र बनाना चाहते हैं या कम करना चाहते हैं या फ़िल्टर करना चाहते हैं, वह बाध्य विधि हो। यदि आप इसे किसी ऑब्जेक्ट से बाध्य नहीं करना चाहते हैं, तो आप "अनबाउंड रैपर" कहते हैं। यह, हालांकि अजीब शब्दावली है क्योंकि आप अंततः (लेकिन आप इसे अनदेखा कर सकते हैं ....) –

+0

ठीक है अपनी खुद की वस्तु के लिए इस विधि बाध्यकारी रहे हैं, मैं क्या समझ में आ से निम्नलिखित बयानों के बराबर हैं: Function.call.apply (Foo.prototype.method, तर्क); Foo.prototype.method.apply (तर्क [0], Array.prototype.slice.call (तर्क, 1)); दोनों को अनबाउंड रैपर बनाने के लिए प्रतिस्थापित किया जा सकता है। हालांकि, पहली विधि कम, तेज और अधिक सहज है। बहुत बढ़िया! –

4

इसका मतलब है कि आप किसी ऑब्जेक्ट से किसी अन्य ऑब्जेक्ट का उपयोग कर सकते हैं।

एक अच्छा उदाहरण तर्क चर सभी कार्य है, यह एक सरणी की तरह है, लेकिन नहीं तो आप इस प्रकार उस पर सरणी के तरीकों कॉल कर सकते हैं एक सरणी:

Array.prototype.join.call(arguments, ","); 
+1

लेकिन मूल प्रश्न में 'लागू' बिट क्या करता है? –

+1

@ कैमरून स्किनर: फ़ंक्शन ऑब्जेक्ट की 'लागू' विधि उस कार्य को निष्पादित करती है, जो कि पहले निष्पादन को उस निष्पादन में 'इस' के रूप में मानती है और दूसरा तर्क 'तर्क' के रूप में होता है। 'fn.apply (ए, [बी, सी])' 'fn.call (ए, बी, सी)' के बराबर है। – eyelidlessness

संबंधित मुद्दे