2011-09-21 7 views
16

मैं विभिन्न पुस्तकालयों के माध्यम से देख रहा हूं, और विस्तार() को बहुत अधिक पॉप अप देख रहा हूं, लेकिन मैं mixin() को भी दिखा रहा हूं। यूयूआई में दोनों मिश्रण और एक्सटेंशन हैं।जावास्क्रिप्ट पुस्तकालयों में mixin() और विस्तार() के बीच क्या अंतर है

इन दो अवधारणाओं के बीच क्या अंतर है? मैं एक मिश्रण के बीच फैसला और एक वस्तु का विस्तार कब होगा?

धन्यवाद, मैट

उत्तर

16

मिक्सिन उदाहरण के साथ काम नहीं करते हैं लेकिन विस्तार करते हैं। मिक्सिन्स एकाधिक विरासत की अनुमति देता है लेकिन इसे फिक्र करके, प्रोटोटाइप को सही ढंग से चेन करके नहीं।

मैं एक Ext-जे एस उदाहरण दिखाता हूँ लेकिन अवधारणा है कि mixins प्रदान करता है किसी भी वर्ग पुस्तकालय पर लागू होता है, वे सब सिर्फ गुण वस्तु के बजाय प्रोटोटाइप चेनिंग की नकल।

Ext.define('Ext.Window', { 
    extend: 'Ext.Panel', 
    requires: 'Ext.Tool', 
    mixins: { 
     draggable: 'Ext.util.Draggable' 
    } 
}); 

Ext.Window instanceof Ext.Panel //true 
Ext.Window instanceof Ext.util.Draggable // false 

मिक्सिन विरासत का उपयोग किए बिना किसी ऑब्जेक्ट में कुछ कार्यक्षमता जोड़ने का एक शानदार तरीका है। यदि आपको कुछ कार्यक्षमता प्राप्त करने के लिए कुछ प्राप्त करना है, तो आप दो कक्षा से कार्यक्षमता का उपयोग नहीं कर सकते हैं। Many people believe it's evil

एक्स्ट-जेएस उस समस्या का अनुभव करते थे जब वे Labelable कार्यक्षमता FieldSet और अन्य जो फ़ील्ड जैसे इनपुट नहीं थे, जोड़ना चाहते थे। व्यवहार Field के अंदर व्यवहार से इसका कोई फायदा नहीं हुआ क्योंकि वे Field का विस्तार नहीं कर सके क्योंकि इसमें भी सभी इनपुट व्यवहार थे।

+1

यह उत्तर Ext.js के लिए बहुत विशिष्ट है और कई अन्य जावास्क्रिप्ट पुस्तकालयों पर लागू नहीं है (jQuery और अंडरस्कोर केवल दो उदाहरण हैं)। – natlee75

+0

@ natlee75 मेरा जवाब कह रही है कि mixins प्रोटोटाइप श्रृंखला का उपयोग नहीं करते हैं, और यह 'विफल रहता है instanceof' परीक्षण, Ext-जे एस उनमें से एक कार्यान्वयन है (वे अगर कुछ एक अलग तरीके से एक mixin है आप जाँच करें)। जहां तक ​​मुझे पता है, jquery या underscore प्रोटोटाइप श्रृंखला में सेट करके मिश्रण को कार्यान्वित नहीं करता है (वे केवल गुणों की प्रतिलिपि बनाते हैं)। आपकी टिप्पणी का तात्पर्य है कि jquery और underscore में mixins हो सकते हैं जो उदाहरण के साथ सही ढंग से काम करते हैं? कृपया विस्तृत करें/ –

+2

नहीं, लेकिन उनके 'विस्तार' कार्य या तो नहीं करते हैं। केवल "कक्षा पुस्तकालय" (जैसे 'Ext.define') प्रोटोटाइपिकल विरासत के लिए" विस्तार "शब्द का उपयोग करते हैं। – Bergi

0

स्पष्टता के लिए संपादित करें: ये कभी कभी एक ही बात है और कभी कभी नहीं हैं; मिक्स्ड एक ऑब्जेक्ट का नाम है जो एकाधिक ऑब्जेक्ट्स के बीच फ़ंक्शंस का पुन: उपयोग करने के लिए उपयोग किया जाता है, और विस्तार करने के लिए उपयोग किए जाने वाले एल्गोरिदम/विधि का विस्तार होता है। ऐसे मामले हैं जहां वे समान हैं (उदाहरण के लिए underscores _.extend) और जिन मामलों में वे भिन्न हैं (backbone.js का विस्तार)।

मामले में जहां वे का विस्तार आम तौर पर वस्तु बढ़ाया जा रहा करने के लिए प्रोटोटाइप लिंक होता है, जबकि mixin लक्ष्य पर तरीकों की एक सूची की नक़ल की अलग हैं।

+0

जब आप दो वर्गों के व्यवहार को चाहते हैं तो छोड़कर। इसके लिए विरासत का उपयोग नहीं कर सकते हैं जबतक कि आप कई विरासत में नहीं जाते हैं, जिनके पास स्वयं का समस्या है। –

+0

मुझे यकीन नहीं है कि यह कैसे संबंधित है, क्योंकि विस्तार और मिश्रण सीधे विरासत से संबंधित नहीं हैं, वे केवल उस व्यवहार की नकल करने के लिए एक विधि हैं। – taxilian

+0

मैं सिर्फ उस मामले को समझा रहा हूं जहां उनके पास समान व्यवहार नहीं है। –

2

आप निश्चित रूप से विस्तार का उपयोग करके मिश्रण बना सकते हैं।

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

हीरा समस्या तब होती है जब एक ऑब्जेक्ट दो ऑब्जेक्ट्स से एक ही फ़ंक्शन (या यहां तक ​​कि फ़ंक्शन नाम) प्राप्त करता है। क्यूं कर? यदि उन दो वस्तुओं में से एक ने फ़ंक्शन को संशोधित किया है, कार्यक्षमता जोड़ना (यानी जावा में "सुपर" कहा जाता है), जावास्क्रिप्ट को यह नहीं पता कि दो विधियों को कैसे समझें/गठबंधन करें। मिक्सिन इस विरासत से बचने का एक तरीका है। वे कार्यक्षमता को परिभाषित करते हैं जिसे आप कहीं भी चिपक सकते हैं। मिक्सिन्स में आमतौर पर स्वयं का डेटा नहीं होता है।

तो मैं, उदाहरण के लिए, एक mixin jQuery में $.extend() साथ लिख सकते हैं। var newmixin = $.extend({}, mixin1, mixin2) दो इंटरफेस को जोड़ देगा, और उन्हें फ़्लैट करेगा (नाम विवादों को ओवरराइट करें)।

  1. दो इंटरफेस के संयोजन "पदानुक्रम" यानी होते हैं:

    यहाँ 3 बातों पर विचार करने के लिए कर रहे हैं। अभिभावक/बाल संबंध। जावास्क्रिप्ट में इसका मतलब प्रोटोटाइप विरासत होगा।

  2. क्या फ़ंक्शंस कॉपी किए गए हैं, या संदर्भित हैं? यदि मूल विधि बदलती है, तो क्या विरासत विधियां भी बदली जाएंगी?
  3. क्या होता है जब एक ही नाम के दो तरीके जोड़ दिया जाता है? और इन संघर्षों के साथ कैसे निपटाया जाता है?
5

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

"Mixin" एक डिजाइन पैटर्न है जिसमें आप गुण और विधियों आप अपने सिस्टम में कई वस्तुओं भर में साझा करना चाहते हैं की एक विशेष सेट के लिए कंटेनर का एक प्रकार के रूप में एक वस्तु का उपयोग करने के लिए संदर्भित करता है। उदाहरण के लिए, आपके पास चौड़ाई और ऊंचाई गेटर्स और सेटर्स हो सकते हैं जो आपके एप्लिकेशन में सभी यूआई घटकों पर लागू हो सकते हैं और इसलिए आप जावास्क्रिप्ट के मामले में बनाएंगे, या तो एक ऐसा फ़ंक्शन जिसे "नया" या ऑब्जेक्ट शाब्दिक के साथ तुरंत चालू किया जा सकता है इन तरीकों को रखता है। फिर आप अपने सिस्टम में किसी भी ऑब्जेक्ट पर इन तरीकों की प्रतिलिपि बनाने के लिए "विस्तार" प्रकार फ़ंक्शन का उपयोग कर सकते हैं।

अंडरस्कोर एक mixin तरीका है कि अनिवार्य रूप से सिर्फ एक का विस्तार जहां वस्तुओं 'तरीकों में पारित आधार से जुड़ जाते हैं के सभी चेनिंग में उपयोग के लिए वस्तु को रेखांकित किया है। jQuery jQuery.fn की विस्तारित विधि के साथ एक समान चीज़ करता है।

व्यक्तिगत रूप से मुझे विस्तार करना पसंद है, "इन ऑब्जेक्ट्स से इस ऑब्जेक्ट में सबकुछ कॉपी करें" टाइप व्यवहार, जबकि एक अलग मिश्रण विधि है, जिसके बजाय केवल एक स्रोत ऑब्जेक्ट स्वीकार करता है और फिर गुणों के नाम के रूप में सभी अन्य तर्कों का व्यवहार करता है और प्रतिलिपि बनाने के तरीके (यदि केवल लक्ष्य और स्रोत को आगे तर्क के साथ पास नहीं किया जाता है तो यह केवल एकल स्रोत विस्तार की तरह कार्य करता है)।

उदा।

function mixin(target, source) { 
    function copyProperty(key) { 
     target[key] = source[key]; 
    } 

    if (arguments.length > 2) { 
     // If there are arguments beyond target and source then treat them as 
     // keys of the specific properties/methods that should be copied over. 
     Array.prototype.slice.call(arguments, 2).forEach(copyProperty); 
    } else { 
     // Otherwise copy all properties/methods from the source to the target. 
     Object.keys(source).forEach(copyProperty); 
    } 
} 
+1

आप मुझे बता सकते हैं क्यों 'करना होगा Array.prototype.slice.call (तर्क , 2) 'over 'arguments.slice (2)'। बस जानना चाहते हैं कि यह कब उपयोगी है। अग्रिम – cantfindaname88

+3

@ cantfindaname88 में धन्यवाद: 'arguments', जबकि' Array' की तरह, एक 'Array' उदाहरण नहीं है, इसलिए यह कोई' .slice() 'विधि है। –

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