2009-07-08 19 views
16

मैं अपने सिर में सीधे jQuery-शैली फ़ंक्शन चेन करने के सिद्धांतों को प्राप्त करने का प्रयास कर रहा हूं। इसके द्वारा मेरा मतलब है:जावास्क्रिप्ट में मूल ऑब्जेक्ट/फ़ंक्शन चेनिंग कार्य कैसे करता है?

var e = f1('test').f2().f3(); 

मुझे काम करने के लिए एक उदाहरण मिला है, जबकि दूसरा नहीं है। मैं नीचे उनको पोस्ट करूंगा। मैं हमेशा कुछ सिद्धांतों को सीखना चाहता हूं कि कुछ कैसे काम करता है ताकि मैं इसके शीर्ष पर निर्माण कर सकूं। अब तक, मेरे पास केवल काम करने वाली चीजों की एक सरसरी और ढीली समझ है और मैं उन बग्स में दौड़ रहा हूं जिन्हें मैं बुद्धिमानी से समस्या निवारण नहीं कर सकता।

मुझे क्या पता:

  1. कार्य, खुद को वापस लौटाना होगा उर्फ ​​"यह वापसी,"
  2. चेनबल फ़ंक्शन एक पैरेंट फ़ंक्शन में रहना चाहिए, jQuery में उर्फ, .css() jQuery() का एक उप तरीका है, इसलिए jQuery()। Css();
  3. पैरेंट फ़ंक्शन या तो खुद को या स्वयं का एक नया उदाहरण लौटा देना चाहिए।

इस उदाहरण काम किया:

var one = function(num){ 
    this.oldnum = num; 

    this.add = function(){ 
     this.oldnum++; 
     return this; 
    } 

    if(this instanceof one){ 
     return this.one;  
    }else{ 
     return new one(num);  
    } 
} 
var test = one(1).add().add(); 

लेकिन यह एक नहीं करता है:

var gmap = function(){ 

    this.add = function(){ 
     alert('add'); 

     return this;  
    } 

    if(this instanceof gmap) { 
     return this.gmap; 
    } else{ 
     return new gmap(); 
    } 

} 
var test = gmap.add(); 
+6

फ़ंक्शंस स्वयं को वापस नहीं करते हैं, वे उस ऑब्जेक्ट को वापस करते हैं जो आपके द्वारा चुने गए तरीकों का समर्थन करता है। JQuery मामले में, यह नोड संचालित किया जा रहा है। – drudru

+1

प्रत्येक फ़ंक्शन को 'इसे वापस करें' के साथ समाप्त करें; '। –

+0

@MarcB - मुझे पता है, लेकिन कैसे? –

उत्तर

32

जावास्क्रिप्ट कार्यों में प्रथम श्रेणी वस्तुओं रहे हैं। जब आप किसी फ़ंक्शन को परिभाषित करते हैं, तो वह उस फ़ंक्शन ऑब्जेक्ट के लिए कन्स्ट्रक्टर होता है। दूसरे शब्दों में:

var gmap = function() { 
    this.add = function() { 
     alert('add'); 
    return this; 
    } 

    this.del = function() { 
     alert('delete'); 
     return this; 
    } 

    if (this instanceof gmap) { 
     return this.gmap; 
    } else { 
     return new gmap(); 
    } 
} 
var test = new gmap(); 
test.add().del(); 

चर परीक्षण करने के लिए

new gmap();
आवंटित करके आप अब एक नया उद्देश्य यह है कि "विरासत" सभी गुण और विधियों gmap() निर्माता (वर्ग) से निर्माण किया है। यदि आप उपरोक्त स्निपेट चलाते हैं तो आपको "एड" और "डिलीट" के लिए एक अलर्ट दिखाई देगा।

उपर्युक्त उदाहरणों में, "यह" विंडो ऑब्जेक्ट को संदर्भित करता है, जब तक आप किसी अन्य फ़ंक्शन या ऑब्जेक्ट में फ़ंक्शन को लपेट नहीं लेते।

श्रृंखलन, मुझे पहली बार में समझने के लिए मुश्किल है कम से कम यह मेरे लिए था, लेकिन एक बार मैं यह समझ, मैं एक उपकरण यह हो सकता है की कितना शक्तिशाली महसूस किया।

4

अफसोस की बात है, सीधा जवाब 'नहीं' होना चाहिए। यहां तक ​​कि अगर आप मौजूदा तरीकों (जो आप शायद कई यूएएस में है, लेकिन मैं IE में नहीं कर सकते हैं पर शक कर सकते हैं) ओवरराइड कर सकते हैं, आप अभी भी बुरा renames के साथ फंस होगी:

HTMLElement.prototype.setAttribute = function(attr) { 
    HTMLElement.prototype.setAttribute(attr) //uh-oh; 
} 
सबसे अच्छा आप शायद दूर के साथ मिल सकता है

HTMLElement.prototype.setAttr = function(attr) { 
    HTMLElement.prototype.setAttribute(attr); 
    return this; 
} 
+0

ऐसा लगता है कि मैं चेनिंग के लिए jQuery पर रहूंगा! –

+1

कृपया ध्यान दें कि यह उत्तर [एक अलग प्रश्न] है (http://stackoverflow.com/questions/10965781) – kojiro

1

"पुनर्लेखन" एक समारोह, लेकिन अभी भी मूल संस्करण का उपयोग करने के लिए, आपको पहले एक अलग चर करने के लिए मूल कार्य असाइन करना होगा सक्षम होने के लिए: एक अलग नाम का उपयोग कर रहा है। एक उदाहरण वस्तु मान लें:

function MyObject() { }; 

MyObject.prototype.func1 = function(a, b) { }; 

chainability के लिए func1 पुनर्लेखन करने के लिए, ऐसा करते हैं:

MyObject.prototype.std_func1 = MyObject.prototype.func1; 
MyObject.prototype.func1 = function(a, b) { 
    this.std_func1(a, b); 
    return this; 
}; 

यहाँ एक working example है। आपको बस उस तकनीक को उन सभी मानक वस्तुओं पर नियोजित करने की आवश्यकता है जिन्हें आपको लगता है कि श्रृंखला की आवश्यकता है।

बार जब आप इस सभी काम कर करके, आप का एहसास हो सकता है वहाँ बेहतर तरीके तुम क्या करने की कोशिश कर रहे हैं क्या, एक पुस्तकालय है कि पहले से ही में बनाया गया chainability है का उपयोग कर की तरह पूरा करने के लिए कर रहे हैं कि। * खांसी * jQuery * खांसी *

+0

यहां एक सामान्य समाधान है: http://stackoverflow.com/a/15797662/162793 – sheldonh

-3

बस विधि को var test = gmap() के रूप में कॉल करें।();

gmap के रूप में कार्य नहीं है एक चर

+0

यह काम नहीं करेगा क्योंकि 'add'' gmap() 'पर परिभाषित नहीं है, लेकिन केवल 'new gmap()' पर है। –

0

सबसे पहले, मुझे बताया गया है कि मैं अपने ही शब्दों में इस समझा रहा करते हैं।

विधि चेनिंग किसी अन्य कार्य/विधि द्वारा वापस आने वाली वस्तु का एक तरीका कह रहा है। (उदाहरण के लिए jQuery का उपयोग):

$('#demo'); 

इस jQuery समारोह का चयन करता है और एक jQuery वस्तु आईडी डेमो के साथ डोम तत्व देता है। यदि तत्व एक पाठ नोड (तत्व) था, तो हम लौटाए गए ऑब्जेक्ट की विधि पर श्रृंखला बना सकते थे। उदाहरण के लिए:

$('#demo').text('Some Text'); 

तो, जब तक एक समारोह/विधि एक वस्तु के रूप में देता है, तो आप मूल बयान के श्रृंखला लौटे वस्तु की एक विधि कर सकते हैं।

क्यों बाद वाले काम नहीं करते हैं, इस बात पर ध्यान दें कि कीवर्ड this का उपयोग कब और कब किया जाता है। यह एक संदर्भ मुद्दा सबसे अधिक संभावना है। जब आप this पर कॉल कर रहे हैं, तो सुनिश्चित करें कि this उस कार्य ऑब्जेक्ट का जिक्र कर रहा है, न कि विंडो ऑब्जेक्ट/वैश्विक दायरा।

उम्मीद है कि मदद करता है।

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