2012-02-18 9 views
16

मेरे पास मेरे पूरे जीवन के दौरान उपयोगी कार्यों का एक गुच्छा है।प्रोटोटाइप का उपयोग किए बिना चेन फ़ंक्शन कैसे करें?

function one(num){ 
    return num+1; 
} 

function two(num){ 
    return num+2; 
} 

मैं उन्हें two(two(one(5)))

साथ कॉल कर सकते हैं लेकिन मैं का उपयोग करने के (5).one().two().two()

मैं कैसे इस प्रोटोटाइप का उपयोग किए बिना प्राप्त कर सकते हैं पसंद करेंगे?

मैं कैसे काम करता है श्रृंखला को रेखांकित देखने के लिए कोशिश की, लेकिन उनके कोड को समझने के लिए यह

+1

, हां, वे वे कार्य हैं जिन्हें मैं एकत्रित कर रहा हूं ... – mithril333221

उत्तर

22

डॉट वाक्य रचना वस्तुओं के लिए आरक्षित है बहुत तीव्र है। तो अगर आप की तरह

function MyNumber(n) { 
    var internal = Number(n); 
    this.one = function() { 
     internal += 1; 
     // here comes the magic that allows chaining: 
     return this; 
    } 
    // this.two analogous 
    this.valueOf = function() { 
     return internal; 
    } 
} 

new MyNumber(5).one().two().two().valueOf(); // 10 

कुछ कर सकते हैं या आप देशी संख्या वस्तु/समारोह के प्रोटोटाइप पर इन तरीकों को लागू करने के लिए जा रहे हैं। यही कारण है कि अनुमति होगी (5).one()...

+0

बेशक आपको प्रोटोटाइप के साथ 'MyNumber' चीज़ को भी लागू करना चाहिए, क्योंकि यह बहुत अधिक कुशल है। – Bergi

+0

'valueOf()' जरूरी है ?, मेरा मतलब है, क्या मुझे हमेशा अपनी श्रृंखलाओं को किसी प्रकार के फ़ंक्शन के साथ समाप्त करना होगा जो वैल लौटाता है? – mithril333221

+0

@ mithril333221 - चेनिंग कार्य करने के लिए, प्रत्येक विधि से वापसी मूल्य सही प्रकार का ऑब्जेक्ट होना चाहिए। यदि आप ऑब्जेक्ट से बाहर कुछ और चाहते हैं, तो आपको उस जानकारी को प्राप्त करने के लिए एक विधि कॉल करनी होगी। – jfriend00

4

अच्छा और सामान्य विकल्प एक कस्टम समारोह रचना समारोह पैदा कर रही है

var go = function(x, fs){ 
    for(var i=0; i < fs.length; i++){ 
     x = fs[i](x); 
    } 
    return x; 
} 

आप इस तरह यह कॉल कर सकते हैं:

go(5, [one, two, two]) 

मैं personaly विधि के एक बड़े प्रशंसक नहीं हूँ चूंकि यह आपको कार्यों के एक पूर्वनिर्धारित सेट पर प्रतिबंधित करता है और "चेनिंग ऑब्जेक्ट" के अंदर मूल्यों और बाहर के मुक्त मूल्यों के बीच एक प्रतिबाधा विसंगति है।

+0

मैं जानना चाहता हूं कि – mithril333221

+0

क्या प्रतिबंध हैं मेरा मतलब था कि यदि आप "चेनिंग विधि" अपमान करना चाहते हैं तो आपको यह जानने की ज़रूरत है कि सभी श्रृंखलाएं क्या हैं विधियां तब होती हैं जब आप चेनर को परिभाषित करते हैं (क्योंकि आपको प्रत्येक फ़ंक्शन के लिए चेनर प्रोटोटाइप में एक विधि जोड़ने की आवश्यकता होती है)। दूसरी ओर, फ़ंक्शन संरचना संस्करण को पहले से ही कार्यों को जानने की आवश्यकता नहीं है ताकि आप जो भी चाहें उसे पार कर सकें इसके लिए – hugomg

+0

फिर भी, आप हर बार प्रोटोटाइप में फ़ंक्शंस जोड़ सकते हैं; समस्या यह है कि उन्हें 'इसे वापस करने' के साथ चेनर निर्माण में फिट होना होगा और 'this._value' का उपयोग करना होगा। संरचना का नकारात्मक भाग है कि एक लाइब्रेरी वैश्विक नामस्थान को प्रदूषित करेगी, और उन्हें एक साथ खींचने के लिए एक नामस्थान रचना वाक्यविन्यास को कठिन बनाता है। – Bergi

6

श्रृंखला के अंत में @ बर्गि के समाधान के रूप में toValue पर कॉल करने से बचने के लिए, आप संलग्न विधियों के साथ एक फ़ंक्शन का उपयोग कर सकते हैं। जेएस इसे एक प्राचीन प्रकार में बदलने की कोशिश करते समय toValue स्वचालित रूप से कॉल करेगा।

function MyNumber(n) { 
    function x() { } 
    x.one = function() { n++; return this; }; 
    x.valueOf = function() { return n; }; 
    return x; 
} 

फिर,

MyNumber(5).one().one() 
> 7 
0

एक अन्य विकल्प lodash flow समारोह का प्रयोग है। उदाहरण के लिए:

var five = _.flow(one, two, two) 
five(5) 

मैं एक चर के लिए एक नई श्रृंखला असाइन करना पसंद करता हूं। यह इसे एक स्पष्ट नाम देता है और पुन: उपयोग को प्रोत्साहित करता है।

बीटीडब्ल्यू, लॉनाश श्रृंखला के कार्यों के लिए अतिरिक्त तर्क पारित करने में भी मदद करता है। उदाहरण के लिए:

var addFive = _.flow(
    _.partialRight(_.add, 1), 
    _.partialRight(_.add, 2), 
    _.partialRight(_.add, 2) 
) 

कार्यात्मक श्रृंखलन में मदद करने के लिए कई अन्य उपयोगी कार्यों के होते हैं, जैसे, आंशिक, फैल, फ्लिप, निगेट, आदि सिर्फ रिकार्ड के लिए