प्रोटोटाइप-आधारित प्रोग्रामिंग

प्रोटोटाइप-आधारित प्रोग्रामिंग ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग की एक शैली है जिसमें व्यवहार पुन: उपयोग (विरासत (प्रोग्रामिंग) के रूप में जाना जाता है) मौजूदा वस्तु (प्रोग्रामिंग) के पुन: उपयोग की प्रक्रिया के माध्यम से किया जाता है जो प्रोटोटाइप के रूप में कार्य करता है। इस मॉडल को प्रोटोटाइप, प्रोटोटाइप-ओरिएंटेड क्लासलेस, या इंस्टेंस-आधारित प्रोग्रामिंग के रूप में भी जाना जा सकता है।

प्रोटोटाइप-आधारित प्रोग्रामिंग सामान्यीकृत वस्तुओं की प्रक्रिया का उपयोग करती है, जिसे बाद में क्लोन और विस्तारित किया जा सकता है। एक उदाहरण के रूप में फल का उपयोग करते हुए, एक फल वस्तु सामान्य रूप से फलों के गुणों और कार्यक्षमता का प्रतिनिधित्व करेगी। एक केले की वस्तु को फल की वस्तु से क्लोन किया जाएगा और केले के लिए विशिष्ट सामान्य गुणों को जोड़ा जाएगा। प्रत्येक व्यक्ति केले की वस्तु को सामान्य केले की वस्तु से क्लोन किया जाएगा। कक्षा आधारित प्रोग्रामिंग|क्लास-बेस्ड पैराडाइम से तुलना करें, जहां एक फ्रूट क्लास को बनाना क्लास द्वारा बढ़ाया जाएगा।

पहली प्रोटोटाइप-ओरिएंटेड प्रोग्रामिंग लैंग्वेज स्वयं (प्रोग्रामिंग भाषा) थी, जिसे 1980 के दशक के मध्य में डेविड अनगर और रान्डेल स्मिथ द्वारा ऑब्जेक्ट-ओरिएंटेड लैंग्वेज डिज़ाइन में विषयों पर शोध करने के लिए विकसित किया गया था। 1990 के दशक के उत्तरार्ध से, वर्गहीन प्रतिमान तेजी से लोकप्रिय हुआ है। कुछ वर्तमान प्रोटोटाइप-उन्मुख भाषाएँ हैं जावास्क्रिप्ट (और अन्य ECMAScript कार्यान्वयन जैसे JScript और Adobe Flash का ActionScript 1.0), Lua (प्रोग्रामिंग भाषा), सेसिल (प्रोग्रामिंग भाषा), न्यूटनस्क्रिप्ट, Io (प्रोग्रामिंग भाषा), Ioke (प्रोग्रामिंग भाषा), MOO (प्रोग्रामिंग भाषा), REBOL और AutoHotkey।

डिजाइन और कार्यान्वयन
जावास्क्रिप्ट में प्रोटोटाइप विरासत का वर्णन डगलस क्रॉकफोर्ड द्वारा किया गया है "You make prototype objects, and then … make new instances. Objects are mutable in JavaScript, so we can augment the new instances, giving them new fields and methods. These can then act as prototypes for even newer objects. We don't need classes to make lots of similar objects… Objects inherit from objects. What could be more object oriented than that?"

प्रोटोटाइप-आधारित प्रोग्रामिंग के अधिवक्ताओं का तर्क है कि यह प्रोग्रामर को उदाहरणों के कुछ सेट के व्यवहार पर ध्यान केंद्रित करने के लिए प्रोत्साहित करता है और केवल बाद में इन वस्तुओं को आर्किटेपल ऑब्जेक्ट्स में वर्गीकृत करने के बारे में चिंता करता है जो बाद में वर्ग (प्रोग्रामिंग) के समान फैशन में उपयोग किए जाते हैं। कई प्रोटोटाइप-आधारित प्रणालियाँ रन टाइम (प्रोग्राम जीवनचक्र चरण) | रन-टाइम के दौरान प्रोटोटाइप के परिवर्तन को प्रोत्साहित करती हैं, जबकि केवल बहुत कम वर्ग-आधारित ऑब्जेक्ट-ओरिएंटेड सिस्टम (जैसे डायनेमिक ऑब्जेक्ट-ओरिएंटेड सिस्टम, सामान्य लिस्प, डायलन (प्रोग्रामिंग) लैंग्वेज), उद्देश्य सी, पर्ल, पायथन (प्रोग्रामिंग लैंग्वेज), रूबी (प्रोग्रामिंग भाषा), या स्मॉलटाक) किसी प्रोग्राम के निष्पादन के दौरान कक्षाओं को बदलने की अनुमति देते हैं।

लगभग सभी प्रोटोटाइप-आधारित प्रणालियाँ व्याख्या की गई भाषा और गतिशील रूप से टाइप की गई भाषाओं पर आधारित हैं। हालाँकि, वैधानिक रूप से टाइप की गई भाषाओं पर आधारित प्रणालियाँ तकनीकी रूप से व्यवहार्य हैं। प्रोटोटाइप-आधारित प्रोग्रामिंग में चर्चा की गई ओमेगा भाषा ऐसी प्रणाली का एक उदाहरण है, हालांकि ओमेगा की वेबसाइट के अनुसार भी ओमेगा विशेष रूप से स्थिर नहीं है, बल्कि इसका संकलक स्थैतिक बंधन का उपयोग करना चुन सकता है जहां यह संभव है और कार्यक्रम की दक्षता में सुधार कर सकता है।

वस्तु निर्माण
प्रोटोटाइप-आधारित भाषाओं में स्पष्ट वर्ग नहीं होते हैं। ऑब्जेक्ट एक प्रोटोटाइप संपत्ति के माध्यम से अन्य वस्तुओं से सीधे प्राप्त होते हैं। प्रोटोटाइप संपत्ति कहा जाता है  स्व (प्रोग्रामिंग भाषा) और जावास्क्रिप्ट में, या   आईओ (प्रोग्रामिंग भाषा) में। नई वस्तुओं के निर्माण की दो विधियाँ हैं: पूर्व निहिलो (कुछ नहीं से) वस्तु निर्माण या किसी मौजूदा वस्तु की क्लोनिंग के माध्यम से। पूर्व को ऑब्जेक्ट लिटरल (कंप्यूटर प्रोग्रामिंग) के कुछ रूपों के माध्यम से समर्थित किया जाता है, घोषणाएं जहां वस्तुओं को रनटाइम पर विशेष सिंटैक्स के माध्यम से परिभाषित किया जा सकता है जैसे   और सीधे एक चर के पास गया। जबकि अधिकांश प्रणालियाँ विभिन्न प्रकार के क्लोनिंग का समर्थन करती हैं, पूर्व निहिलो वस्तु निर्माण उतना प्रमुख नहीं है। क्लास-आधारित भाषाओं में, एक क्लास के कंस्ट्रक्टर (कंप्यूटर साइंस) के माध्यम से एक नया उदाहरण बनाया जाता है, एक विशेष फ़ंक्शन जो ऑब्जेक्ट के सदस्यों (गुणों और विधियों) के लिए मेमोरी का एक ब्लॉक आरक्षित करता है और उस ब्लॉक का संदर्भ देता है। कन्स्ट्रक्टर पैरामीटर (कंप्यूटर साइंस) का एक वैकल्पिक सेट फ़ंक्शन में पारित किया जा सकता है और आमतौर पर गुणों में आयोजित किया जाता है। परिणामी उदाहरण वर्ग में परिभाषित सभी विधियों और गुणों को इनहेरिट करेगा, जो एक प्रकार के टेम्पलेट के रूप में कार्य करता है जिससे समान टाइप की गई वस्तुओं का निर्माण किया जा सकता है।

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

क्लोनिंग एक ऐसी प्रक्रिया को संदर्भित करता है जिससे किसी मौजूदा वस्तु (उसके प्रोटोटाइप) के व्यवहार की नकल करके एक नई वस्तु का निर्माण किया जाता है। नई वस्तु तब मूल के सभी गुणों को वहन करती है। इस बिंदु से, नई वस्तु को संशोधित किया जा सकता है। कुछ प्रणालियों में परिणामी चाइल्ड ऑब्जेक्ट अपने प्रोटोटाइप के लिए एक स्पष्ट लिंक (डेलिगेशन (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) या समानता (प्रोग्रामिंग) के माध्यम से) को बनाए रखता है, और प्रोटोटाइप में बदलाव के कारण इसके क्लोन में स्पष्ट परिवर्तन होते हैं। अन्य प्रणालियाँ, जैसे फोर्थ (प्रोग्रामिंग भाषा) जैसी प्रोग्रामिंग भाषा केवो (प्रोग्रामिंग भाषा), इस तरह से प्रोटोटाइप से परिवर्तन का प्रचार नहीं करती हैं और इसके बजाय एक अधिक सुसंगत मॉडल का पालन करती हैं, जहाँ क्लोन ऑब्जेक्ट्स में परिवर्तन स्वचालित रूप से वंशजों में नहीं फैलते हैं। <वाक्यविन्यास हाइलाइट लैंग = जावास्क्रिप्ट> // असली प्रोटोटाइप इनहेरिटेंस स्टाइल का उदाहरण // जावास्क्रिप्ट में।

// वस्तु निर्माण शाब्दिक का उपयोग कर // ऑब्जेक्ट नोटेशन {}। कॉन्स्ट फू = {नाम: फू, एक: 1, दो: 2};

// दूसरी वस्तु। कॉन्स्ट बार = {दो: दो, तीन: 3};

// Object.setPrototypeOf ECMAScript 2015 में शुरू की गई एक विधि है। // सादगी के लिए, आइए हम दिखावा करें // कि निम्न पंक्ति चाहे कुछ भी काम करे // इंजन का इस्तेमाल किया: Object.setPrototypeOf(बार, फू); // फू अब बार का प्रोटोटाइप है।

// यदि हम फू की संपत्तियों को बार से एक्सेस करने का प्रयास करते हैं // अब से, हम सफल होंगे। बार.एक; // 1 को हल करता है।

// चाइल्ड ऑब्जेक्ट के गुण भी एक्सेस किए जा सकते हैं। बार.तीन; // 3 को हल करता है।

// स्वयं के गुण छाया प्रोटोटाइप गुण बार.दो; // दो को हल करता है बार नाम; // अप्रभावित, फू को हल करता है फू.नाम; // फू को हल करता है 

दूसरे उदाहरण के लिए: <वाक्यविन्यास हाइलाइट लैंग = जावास्क्रिप्ट> कॉन्स्ट फू = {एक: 1, दो: 2};

// bar.prototype = foo कॉन्स्ट बार = ऑब्जेक्ट.क्रिएट (फू);

बार.तीन = 3;

बार.एक; // 1 बार.दो; // 2 बार.तीन; // 3 

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

संयोजन
समसामयिक प्रोटोटाइप में - केवो प्रोग्रामिंग भाषा द्वारा कार्यान्वित दृष्टिकोण - मूल प्रोटोटाइप के लिए कोई दृश्य संकेत या लिंक नहीं हैं जिससे किसी वस्तु का क्लोन बनाया जाता है। प्रोटोटाइप (पैरेंट) ऑब्जेक्ट को लिंक करने के बजाय कॉपी किया गया है और कोई डेलिगेशन नहीं है। नतीजतन, क्लोन किए गए ऑब्जेक्ट्स में प्रोटोटाइप में परिवर्तन दिखाई नहीं देंगे। इस व्यवस्था के तहत मुख्य वैचारिक अंतर यह है कि प्रोटोटाइप ऑब्जेक्ट में किए गए परिवर्तन स्वचालित रूप से क्लोन के लिए प्रचारित नहीं होते हैं। इसे फायदे या नुकसान के तौर पर देखा जा सकता है। (हालांकि, केवो समानता के आधार पर वस्तुओं के सेट में परिवर्तन प्रकाशित करने के लिए अतिरिक्त आदिम प्रदान करता है - तथाकथित पारिवारिक समानताएं या क्लोन परिवार तंत्र - टैक्सोनोमिक उत्पत्ति के बजाय, जैसा कि प्रतिनिधिमंडल मॉडल में विशिष्ट है।) यह भी कभी-कभी दावा किया जाता है कि प्रतिनिधिमंडल-आधारित प्रोटोटाइप में एक अतिरिक्त नुकसान होता है, जो कि बच्चे की वस्तु में परिवर्तन माता-पिता के बाद के संचालन को प्रभावित कर सकता है। हालाँकि, यह समस्या प्रतिनिधिमंडल-आधारित मॉडल में निहित नहीं है और जावास्क्रिप्ट जैसी प्रतिनिधिमंडल-आधारित भाषाओं में मौजूद नहीं है, जो यह सुनिश्चित करती है कि चाइल्ड ऑब्जेक्ट में परिवर्तन हमेशा चाइल्ड ऑब्जेक्ट में ही रिकॉर्ड किए जाते हैं और माता-पिता में कभी नहीं (अर्थात बच्चे के मूल्य माता-पिता के मूल्य को बदलने के बजाय माता-पिता के मूल्य को छाया देता है)।

सरल कार्यान्वयन में, समवर्ती प्रोटोटाइप में प्रतिनिधिमंडल-आधारित प्रोटोटाइप की तुलना में तेज़ सदस्य लुकअप होगा (क्योंकि मूल वस्तुओं की श्रृंखला का पालन करने की कोई आवश्यकता नहीं है), लेकिन इसके विपरीत अधिक मेमोरी का उपयोग करेगा (क्योंकि सभी स्लॉट कॉपी किए गए हैं, बजाय एकल होने के मूल वस्तु की ओर इशारा करते हुए स्लॉट)। हालाँकि, अधिक परिष्कृत कार्यान्वयन इस समस्या से बच सकते हैं, हालाँकि, गति और स्मृति के बीच व्यापार-नापसंद की आवश्यकता होती है। उदाहरण के लिए, समसामयिक प्रोटोटाइप वाली प्रणालियाँ पर्दे के पीछे के डेटा साझा करने की अनुमति देने के लिए लिखने पर नकल कार्यान्वयन का उपयोग कर सकती हैं - और इस तरह के दृष्टिकोण का वास्तव में केवो द्वारा पालन किया जाता है। इसके विपरीत, डेलिगेशन-आधारित प्रोटोटाइप वाले सिस्टम डेटा लुकअप को गति देने के लिए कैश (कंप्यूटिंग) का उपयोग कर सकते हैं।

आलोचना
क्लास-आधारित ऑब्जेक्ट मॉडल के पैरोकार जो प्रोटोटाइप-आधारित सिस्टम की आलोचना करते हैं, अक्सर उन चिंताओं के समान होते हैं जो प्रोग्रामिंग भाषाओं के लिए स्टैटिक टाइप सिस्टम के समर्थकों के पास डायनेमिक टाइप सिस्टम होते हैं (डेटा प्रकार देखें)। आमतौर पर, ऐसी चिंताओं में शुद्धता (कंप्यूटर विज्ञान), प्रकार की सुरक्षा, पूर्वानुमेयता, एल्गोरिथम दक्षता और प्रोग्रामर अपरिचितता शामिल होती है।

पहले तीन बिंदुओं पर, कक्षाओं को अक्सर प्रकारों के अनुरूप देखा जाता है (अधिकांश वैधानिक रूप से टाइप की गई वस्तु-उन्मुख भाषाओं में वे उस भूमिका को पूरा करते हैं) और उनके उदाहरणों और उनके उदाहरणों के उपयोगकर्ताओं को संविदात्मक गारंटी प्रदान करने का प्रस्ताव है, कि वे व्यवहार करेंगे किसी दिए गए फैशन में।

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

प्रोटोटाइप-आधारित भाषाओं के खिलाफ एक आम आलोचना यह है कि जावास्क्रिप्ट की लोकप्रियता और बाजार में प्रवेश के बावजूद सॉफ्टवेयर डेवलपर्स का समुदाय उनसे अपरिचित है। प्रोटोटाइप-आधारित सिस्टम का यह ज्ञान स्तर जावास्क्रिप्ट ढांचा के प्रसार और वर्ल्ड वाइड वेब के परिपक्व होने के साथ जावास्क्रिप्ट के जटिल उपयोग के साथ बढ़ रहा है। ईसीएमएस्क्रिप्ट 6 ने जावास्क्रिप्ट के मौजूदा प्रोटोटाइप-आधारित विरासत पर सिंटैक्टिक चीनी के रूप में कक्षाएं पेश कीं, वस्तुओं को बनाने और विरासत से निपटने का एक वैकल्पिक तरीका प्रदान किया।

प्रोटोटाइप-आधारित प्रोग्रामिंग का समर्थन करने वाली भाषाएं

 * अभिनेता-आधारित समवर्ती भाषा (ABCL): ABCL/1, ABCL/R, ABCL/R2, ABCL/c plus|ABCL/c+
 * अगोरा (प्रोग्रामिंग भाषा)
 * ऑटोहॉटकी
 * क्रेग चेम्बर्स की सेसिल (प्रोग्रामिंग भाषा) और डीजल (प्रोग्रामिंग भाषा)।
 * शीत सी
 * कोला (सॉफ्टवेयर आर्किटेक्चर)
 * सामान्य लिस्प
 * सियान
 * ईसीएमएस्क्रिप्ट
 * ActionScript 1.0, Adobe Flash और Adobe Flex द्वारा उपयोग किया जाता है
 * E4X
 * जावास्क्रिप्ट
 * जेस्क्रिप्ट
 * टाइपप्रति
 * आईओ (प्रोग्रामिंग भाषा)
 * इओके (प्रोग्रामिंग भाषा)
 * जेसननेट (प्रोग्रामिंग भाषा)
 * लोगटॉक
 * एलपीसी (प्रोग्रामिंग भाषा)
 * लुआ (प्रोग्रामिंग भाषा)
 * M2000 दुभाषिया (प्रोग्रामिंग भाषा)
 * मेपल (सॉफ्टवेयर)
 * एमओओ (प्रोग्रामिंग भाषा)
 * नेको (प्रोग्रामिंग भाषा)
 * न्यूटनस्क्रिप्ट
 * निम (प्रोग्रामिंग भाषा)
 * निक्स पैकेज मैनेजर
 * वस्तु लिस्प
 * बूंदा बांदी
 * ओमेगा (प्रोग्रामिंग भाषा)
 * OpenLaszlo
 * पर्ल, क्लास :: प्रोटोटाइप मॉड्यूल के साथ
 * पायथन (प्रोग्रामिंग भाषा) प्रोटोटाइप.py के साथ।
 * आर (प्रोग्रामिंग भाषा), प्रोटो पैकेज के साथ
 * रिबोल
 * लाल (प्रोग्रामिंग भाषा)
 * रूबी (प्रोग्रामिंग भाषा)
 * स्वयं (प्रोग्रामिंग भाषा)
 * सेफ (प्रोग्रामिंग भाषा)
 * स्लेट (प्रोग्रामिंग भाषा)
 * स्मार्टफ्रॉग
 * स्नैप!_(प्रोग्रामिंग_भाषा)|स्नैप!
 * Etoys (प्रोग्रामिंग भाषा)
 * तब
 * स्निट एक्सटेंशन के साथ टीसीएल
 * घोड़ा आदमी

यह भी देखें

 * वर्ग-आधारित प्रोग्रामिंग (विपरीत)
 * विभेदक वंशानुक्रम
 * प्रोग्रामिंग प्रतिमान
 * प्रोटो.आईओ

अग्रिम पठन

 * Class Warfare: Classes vs. Prototypes, by Brian Foote.
 * Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems, by Henry Lieberman, 1986.
 * Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems, by Henry Lieberman, 1986.
 * Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems, by Henry Lieberman, 1986.