2013-08-15 5 views
16

कोई भी यह बता सकता है कि यह फ़ंक्शन अलर्ट कैसे करता है, जब पैरामीटर के ब्रैकेट्स को और अधिक पास नहीं किया जाता है। मैं इसे स्पष्ट रूप से समझने में सक्षम नहीं था।एकाधिक ब्रैकेट्स के साथ जावास्क्रिप्ट में बंद

function sum(a) { 

    var sum = a 

    function f(b) { 
    sum += b 
    return f 
    } 

    f.toString = function() { return sum } 

    return f 
} 

alert(sum(1)(2)) // 3 
alert(sum(5)(-1)(2)) // 6 
alert(sum(6)(-1)(-2)(-3)) // 0 
alert(sum(0)(1)(2)(3)(4)(5)) // 15 

उत्तर

16

पहली बार आपके फ़ंक्शन को कॉल किया जाता है, पहला मान sum में संग्रहीत किया जाता है। उसके बाद function f(b) वापस कर दिया जाएगा, अस्थायी परिणाम sum में बनाए रखा जाएगा। प्रत्येक निरंतर कॉल के साथ आप फ़ंक्शन f निष्पादित करते हैं - आप sum += b निष्पादित करते हैं और फिर से वापस आते हैं। यदि एक स्ट्रिंग संदर्भ की आवश्यकता है (जैसे कि alert, या console.log) f.toString इसके बजाय परिणाम (sum) लौटाया जाता है।

function sum(a) { 

    var sum = a 

    function f(b) { 
    sum += b 
    return f //<- from second call, f is returned each time 
       // so you can chain those calls indefinitely 
       // function sum basically got "overridden" by f 
    } 

    f.toString = function() { return sum } 

    return f //<- after first call, f is returned 
} 

स्पष्टीकरण:

alert(sum(6)(-1)(-2)(-3)) // 0 
      /\ function sum called, f returned 
       /\ the returned function f is called, f returns itself 
        /\ again 
        /\ and again 
         /\ at last, alert() requires string context, 
          so f.toString is getting invoked now instead of f 
+0

मूल रूप से पहली चेतावनी राशि (1) (2) में जो एक और बी है और दूसरी चेतावनी में यह योग (6) (- 1) (2) अब कार्य समझता है कि (2) भी एफ (बी) है) तर्क। – PCA

+0

@ बाबू ए और बी की सोच से छुटकारा पाएं। आप 'sum() 'को एक बार बुलाया जा सकता है,' var sum' शुरू करना और फिर पहली कॉल के बाद ओवर्रिडन प्राप्त करना, 'एफ (बी)' का आह्वान करके प्रत्येक कॉल को संभालना (क्योंकि स्वयं प्रत्येक बार स्वयं लौटता है, इस प्रकार स्वयं जिससे आगे चेनिंग करना संभव हो जाता है) फ़ंक्शन जब तक एक स्ट्रिंग संदर्भ नहीं होता है। अब स्पष्ट है? – Christoph

+0

महान स्पष्टीकरण। क्या आप कृपया मुझे f.toString के बजाय बता सकते हैं क्या आप सीधे राशि वापस करने के लिए मुझे कोड दिखा सकते हैं। समारोह राशि (अ) { वर योग = एक समारोह च (ख) { योग + = ख वापसी राशि } // f.toString = function() {वापसी राशि} वापसी एफ } योग (1) (2); – PCA

2

alert एक स्ट्रिंग की अपेक्षा करता है। यदि यह एक स्ट्रिंग नहीं मिलता है, तो यह किसी भी वस्तु को प्राप्त करने का प्रयास करेगा (और एक कार्य वस्तु का एक प्रकार है) एक में। यदि ऑब्जेक्ट में toString विधि है, तो उसे कहा रूपांतरण करने के लिए कहा जाएगा।

+2

सभी ऑब्जेक्ट्स में 'toString' फ़ंक्शन है, यह केवल इतना है कि ज्यादातर मामलों में यह डिफ़ॉल्ट "[ऑब्जेक्ट कंस्ट्रक्टर्नम]" प्रारूप है। इस मामले में, परिणाम उत्पन्न करने के लिए उस विधि को ओवरराइड किया गया है। –

3

बात को देखने के लिए कोड

function f(b) { 
    sum += b 
    return f 
    } 

के इस टुकड़े इस समारोह में ही संदर्भ देता है तो यह संभव के रूप में कई बार के रूप में कहा जा सकता है। इसके बारे में एक महत्वपूर्ण बात यह है कि यह एक toString समारोह कहा जाता हो जाता है कि है कि और के बाद से toString समारोह sum() अंदर परिभाषित किया गया है यह चर sum और उसका मान वर्तमान मूल्य के लिए उपयोग (कि f() द्वारा बदल दिया गया है) है

1

sum और f फ़ंक्शंस हमेशा f फ़ंक्शन लौटाते हैं, आप फ़ंक्शन के अलावा परिणाम प्राप्त किए बिना अनंत काल का आह्वान कर सकते हैं।

मूल्य केवल f की ओवरराइट toString विधि (जो वास्तव में एक नंबर प्रदान करता है) द्वारा दिया जाता है:

console.log(sum(1)(2)) // Function(){} 
console.log(sum(1)(2).toString()) // 3 

alert समारोह परोक्ष toString विधि invokes जब यह तार करने के लिए अपने तर्कों डाले।

0

के रूप में सभी मामलों में इरादा यह काम नहीं करता है ... समस्या यह है कि .toString एक स्ट्रिंग लौटने की उम्मीद है है, इसलिए प्रदान की कार्यान्वयन में स्ट्रिंग के तरीकों, काम नहीं करेगा, ई। जी। sum(2)(3).split() एक त्रुटि का कारण होगा।

हालांकि हम मान सकते हैं कि sum() परिणाम हमेशा एक संख्या होने की उम्मीद की जाएगी, यह कुछ मामलों में सच नहीं हो सकता है और डीबग करना मुश्किल हो सकता है, ई। जी। मैंने इस मुद्दे को देखा जब मैं शुरुआत में .toString के साथ jsbin.com पर लिखा गया कोड परीक्षण कर रहा था (यह आंतरिक रूप से console.log तर्क पर split करता है, इसे ओवरराइड करता है)।

इसके बजाय, .toStringreturn String(result); जैसा दिखना चाहिए। अच्छी बात यह है कि .toString (जब .valueOf या आधुनिक Symbol.toPrimitive नहीं है) प्राइमेटिव रूपांतरण को संभालेगा, इसलिए संख्या की उम्मीद करने वाला कोड भी काम करेगा। यहां संभावित समस्या "डबल" रूपांतरण हो सकती है।

बेहतर समाधान शायद .toString और .valueOf या केवल Symbol.toPrimitive की जोड़ी का उपयोग करने के लिए हो सकता है यदि आप केवल आधुनिक ब्राउज़र को लक्षित कर रहे हैं।

उदाहरण Symbol.toPrimitive का उपयोग कर:

function sum(a) { 
    let result = a; 

    function f(b) { 
    result += b; 

    return f; 
    } 

    f[Symbol.toPrimitive] = hint => hint === 'string' ? String(result) : result; 

    return f; 
} 

उदाहरण .toString और .valueOf जोड़ी का उपयोग कर।

function sum(a) { 
    var result = a; 

    function f(b) { 
    result += b; 

    return f; 
    } 

    // avoiding double conversion which will happen in case of .toString 
    f.valueOf = function() { return result; }; 
    f.toString = function() { return String(result); }; 

    return f; 
} 
संबंधित मुद्दे