2013-02-14 23 views
16

ऐसे forEach के रूप में JavaScript श्रृंखला तरीकों एक thisArg पैरामीटर, जो कॉलबैक लागू करने के लिए संदर्भ के रूप में प्रयोग किया जाता है है:Array.prototype.reduce का यह ऑब्जेक्ट पैरामीटर क्यों नहीं है?

array.forEach(callback[, thisArg]) 

करते हैं every, some, filter और map। हालांकि, reduce और reduceRight कोई ऐसा पैरामीटर नहीं है। क्या इसके लिए कोई विशेष कारण है, या किसी कारण से यह जरूरी नहीं है?

उदाहरण के लिए, reduceRight का उपयोग कर कार्यात्मक संरचना के निम्नलिखित कार्यान्वयन पर विचार करें:

function compose() { 
    var fns = [].slice.call(arguments,0); 
    return function result() { 
     return fns.reduceRight(
      function (prev,cur){ 
       return [cur.apply(this,prev)]; 
      }, 
      arguments 
     )[0]; 
    }; 
} 

मैं इस "इस अवगत" करना चाहते हैं, तो कार्यों की रचना की जा रही संदर्भ में कहा जाता है जो समारोह में compose द्वारा लौटाया गया है। वर्तमान में वे वैश्विक वस्तु के संदर्भ में शामिल होने लगते हैं। मैं फंक्शन result के शीर्ष पर पुराना var self=this; कर सकता हूं, और इसे cur.apply कॉल के पहले तर्क के रूप में उपयोग करता हूं, जहां वर्तमान में this है, लेकिन reduce ने thisArg तर्क लिया तो यह अनावश्यक होगा।

क्या मुझे यहां कुछ याद आ रही है, और reduce के बारे में कुछ ऐसा है जो इस अनावश्यक या अनुपयोगी बनाता है?

अद्यतन

@kangax हाँ, मुझे लगा कि। एपीआई के डिजाइन की आलोचना करने के लिए मुझसे दूर रहें, लेकिन reduce के लिए हस्ताक्षर मेरे लिए थोड़ा अजीब लगता है। दूसरा वैकल्पिक तर्क सामान्य वैकल्पिक तर्कों से भिन्न रूप से कार्य करता है, जो आमतौर पर केवल एक डिफ़ॉल्ट मान होता है; इसके बजाय इसकी उपस्थिति या अनुपस्थिति व्यवहार को बदलती है, अनिवार्य रूप से हस्ताक्षर (तर्क गणना) के आधार पर फ़ंक्शन को अधिभारित करती है। जब दूसरा पैरामीटर अनुपस्थित है, तो सरणी का पहला तत्व प्रारंभिक मान बन जाता है और कॉलबैक के लिए पहला कॉल दूसरे मान के विरुद्ध होता है। मुझे ऐसा लगता है कि इस व्यवहार को आसानी से बस बुला

array.slice(1).reduce(fn,array[0]) 
मामले के लिए विशेष नियम जहां दूसरा तर्क छोड़ दिया जाता है, जो बारी में, यदि आपका अनुमान सही है, तो भी इसे बनाया में

बजाय इमारत ने अपनाया जा सकता है thisArg तर्क निर्दिष्ट करने के लिए अनिवार्य रूप से असंभव है। फिर फिर, मुझे यकीन है कि इस तरह के मुद्दों पर पहले ही बहस की जा रही थी, जबकि इस तरह के दृष्टिकोण के लिए अच्छे कारण हो सकते थे।

+0

शायद क्योंकि 'कमी' में दूसरा तर्क प्रारंभिक मान – kangax

+0

है क्या आपको 'lowRight'' के साथ ऐसा करने का कोई कारण है? मुझे लगता है कि आप 'रिवर्स' डी ऐरे पर 'forEach' के साथ आसानी से ऐसा कर सकते हैं। संपादित करें: मुझे लगता है कि मेरा मुद्दा यह है कि आप कार्यों की सरणी को कम करने की तलाश नहीं कर रहे हैं, बल्कि कार्यों के माध्यम से इनपुट का एक सेट चलाएं। – tJener

+1

@tJener बेशक आप इसे प्रत्येक के लिए कर सकते हैं (aserscore.js करता है), लेकिन मुझे कम/दाएं का उपयोग करने में एक निश्चित लालित्य मिला। –

उत्तर

4

यह दो वैकल्पिक तर्क के साथ गंदा हो जाता है, के बाद से reduce (Right) पहले से ही दो कार्यक्षमताओं (Wikipedia देखें) है, जो शुद्ध भाषाओं में प्रतिष्ठित हैं को शामिल किया गया है (जैसे foldl और हास्केल में foldl1 नाम)।Brendan Eich उद्धृत करने के लिए:

तो इसका मतलब यह होगा कि एक कॉलबैक तर्क और दो वैकल्पिक तर्क लेते हैं: यह ऑब्जेक्ट और इनिट। कौन सा पहले आना चाहिए? अधिक सामान्य एक शायद init है, लेकिन फिर आप कॉलबैक तर्क को "thisObject" तर्क से अलग करते हैं, जो शायद ठीक है। एकाधिक वैकल्पिक तर्क इस तरह से गड़बड़ कर रहे हैं ...

वैकल्पिक रूप से, हम उस अतिरिक्त "thisObject" तर्क को खत्म कर सकते हैं, क्योंकि लोग हमेशा [बाइंडिंग का उपयोग कर सकते हैं]

मैं यह एक बड़ा मुद्दा है, के बाद से इन कार्यात्मक उच्च क्रम-कार्यों ज्यादातर lamdba- समारोह-भाव के साथ वैसे भी (तरह अपने उदाहरण में) उपयोग किया जाता है नहीं लगता। बेशक वहाँ एक छोटी असंगतता है, लेकिन हम इसके साथ रह सकते हैं। छवि विकल्प:

array.reduce(callback[, initialValue[, thisArg]]) 

वास्तव में इस्तेमाल नहीं किया जा सकता है, हम वास्तव में यह निर्धारित नहीं कर सकते "if an initialValue was provided" के बाद से इसका मतलब है कि arguments.length < 2 - हम undefined सचमुच के साथ-साथ दे सकते हैं। ताकि

array.reduce(callback[, thisArg[, initialValue]]) 

जो बदसूरत है के बाद से हम हमेशा अगर हम केवल एक प्रारंभिक मूल्य चाहता था thisArg को null या कुछ और पारित करने के लिए की जरूरत का मतलब है।

आप Kangax को अपनी टिप्पणी में कि पहले से ही देखा है ("की तुलना में अलग दूसरा वैकल्पिक तर्क कार्यों सामान्य वैकल्पिक तर्क, [...] अपनी उपस्थिति या अनुपस्थिति व्यवहार बदल जाता है"), लेकिन मैं अपने बयान का समर्थन नहीं कर सकते हैं

इस व्यवहार को आसानी से बस बुला array.slice(1).reduce(fn,array[0])

के रूप में है कि एक) एक जटिल (श्रृंखलित) अभिव्यक्ति के बजाय array चर के साथ काम नहीं करेंगे और ख) बोझिल है

ने अपनाया जा सकता है।

3

पर ईएस पर चर्चा मेलिंग सूची आप जवाब में मिल http://article.gmane.org/gmane.comp.lang.javascript.ecmascript4.general/4770

कॉलबैक के साथ अन्य तरीकों लेने के लिए एक 'thisArg' नहीं है क्योंकि यह जरूरत या यहाँ तक कि उपयोगी है, लेकिन संगतता के लिए, क्योंकि वे पहले से ही कर मौजूदा कार्यान्वयन में जो इन कार्यों को प्रदान करते हैं।

+0

अच्छा खोज परिणाम, हालांकि मुझे धागे से अन्य मेल अधिक प्रासंगिक – Bergi

+0

धागे (मार्च 200 9) के समय तक, एक्मास्क्रिप्ट 5 बहुत ही स्थिर था, केवल संपादकीय परिवर्तन से गुजर रहा था। जैसा कि हम जानते हैं कि जावास्क्रिप्ट को 2008 के अंत तक किसी भी डिजाइन तर्कसंगत के साथ सुलझाया गया था। इस तरह मैंने ओपी के सवाल को पढ़ा। –

2

तुम हमेशा इस विधि का उपयोग कर सकते हैं:

array.reduce(callback.bind(context), initialValue); 

... आदेश कॉलबैक फ़ंक्शन पर एक विशिष्ट संदर्भ संलग्न करने में।

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

  • कोई संबंधित समस्या नहीं^_^