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


10

त्वरित पृष्ठभूमि: जावास्क्रिप्ट में, प्रत्येक ऑब्जेक्ट प्रकार के लिए निर्माता फ़ंक्शन में एक prototypeसंपत्ति होती है। prototypeएक वस्तु को संदर्भित करता है कि अपने प्रोटोटाइप श्रृंखला में अगला कदम अप के रूप में प्रत्येक निर्माण वस्तु का उपयोग करता है। जब आप एक प्रकार को दूसरे प्रकार से अंतर्निहित करना चाहते हैं, तो आप prototypeबच्चे के प्रकार को माता-पिता के प्रकार के एक नए उदाहरण में सेट कर सकते हैं ।

उदाहरण के लिए:

var Parent = function() { /* constructor business */ }
Parent.prototype.parentProp = "some parent property";

var Child = function() { /* constructor business */ }
Child.prototype = /*** !! Some prototype object goes here !! ***/

मेरा प्रश्न इस बारे में पूछता है कि Some prototype object goes hereउपरोक्त कोड में " " कोड किस स्थान पर जाना चाहिए । मेरी पहली वृत्ति माता-पिता (यानी new Parent()) का एक उदाहरण का निर्माण करना है , लेकिन इस पर एक जवाब में एक टिप्पणी है कि क्या यह एक वस्तुओं के प्रोटोटाइप को दूसरे की नकल करने का एक सुरक्षित तरीका है? , एक उपयोगकर्ता लिखते हैं:

नहीं, new bar()प्रोटोटाइप ऑब्जेक्ट के लिए उपयोग न करें !

((जो कि एक राय है जो मैंने कई एसओ उत्तर और टिप्पणियों में देखी है, लेकिन यह एकमात्र उदाहरण है जो मेरे हाथ में है।)

अन्य विकल्प के Object.create(Parent.prototype)रूप में उपयोग करना है Child.prototype। जहां तक ​​मुझे पता है, यह एक नया Parentउदाहरण भी बनाता है , लेकिन यह Parentकंस्ट्रक्टर को नहीं चलाता है ।

क्या कोई समझा सकता है कि माता-पिता के प्रकार से प्रोटोटाइप ऑब्जेक्ट बनाते समय कंस्ट्रक्टर फ़ंक्शन को चलाने से क्यों बचा जाना चाहिए? क्या कुछ महत्वपूर्ण तकनीकी समस्या है जो (शायद विरासत के कई स्तरों के साथ) उत्पन्न होती है? या इस तरह का पैटर्न कंस्ट्रक्टर्स का दुरुपयोग है जो कुछ प्रोटोटाइपिक प्रैक्टिस के साथ टकराता है (उदाहरण के लिए, प्रोटोटाइप बनाते समय कंस्ट्रक्टर को चलाना कुछ चिंताओं को अलग करता है)?

जवाबों:


5

क्योंकि यह एक ऐसा फ़ंक्शन है जिसे कॉल करने की आवश्यकता नहीं है। newयह जावास्क्रिप्ट में एक नियमित फ़ंक्शन कॉल से अलग नहीं है।

एक कंस्ट्रक्टर केवल सेट किए गए फ़ील्ड से अधिक कर सकता है। उदाहरण के लिए, यदि यह आने वाले डेटा को मान्य करता है, तो आप एक सत्यापन त्रुटि का कारण बनेंगे जब आप बस वंशानुक्रम श्रृंखला निर्धारित करने का प्रयास कर रहे थे।

और आपको जरूरत नहीं है Object.create, यह पर्याप्त है:

function objectCreate( proto ) {
    function T(){}
    T.prototype = proto;
    return new T();
}

लेकिन वास्तव में इसे कैसे Object.createलागू किया जाता है।
केसी चू

@CaseyChu बिल्कुल नहीं। और मैंने इसका उल्लेख किया क्योंकि लिंक किए गए पोस्ट में किसी ने कहा " Object.createIE8 में काम नहीं करता है" - जो कि केवल बेकार टिप्पणी है जब आप इसे किसी ब्राउज़र पर 2 सेकंड में इस उपयोग के मामले के लिए लागू कर सकते हैं।
एस्लेइजा

2

अब जब मेरी समझ थोड़ी चौड़ी हो गई है, मैं एक विशिष्ट उदाहरण के साथ एस्किला के उत्तर पर निर्माण करना चाहूंगा :

एक विशिष्ट चिंता यह है कि एक निर्माता उदाहरण-विशिष्ट गुण सेट कर सकता है। इस प्रकार, यदि आप के साथ बनाई गई एक प्रोटोटाइप ऑब्जेक्ट का उपयोग करते हैं, तो आपके newसभी बच्चे इंस्टेंसेस प्रोटोटाइप से एकल कंस्ट्रक्टर-निर्धारित आवृत्ति-विशिष्ट गुण साझा कर सकते हैं।

उदाहरण के लिए, मान लें कि Parentप्रत्येक के पास idनिर्माण समय के रूप में एक अद्वितीय संपत्ति है:

var Parent = function() { this.id = Math.random(); }
Parent.prototype.parentProp = "some parent property";

var Child = function() { /* constructor business */ }
Child.prototype = new Parent();

यह सभी Child उदाहरणों को एक idसे प्राप्त एक ही प्रोटोटाइप संपत्ति को साझा करने का कारण बनेगा और केवल उसी new Parent()वस्तु का उपयोग किया जाएगा Child.prototype

इस मामले के लिए एक बेहतर तरीका Object.createबाल निर्माणकर्ता के अंदर मूल निर्माणकर्ता (यदि आवश्यक हो) का उपयोग करना और सीधे कॉल करना है:

var Parent = function() { this.id = Math.random(); }
Parent.prototype.parentProp = "some parent property";

var Child = function() {
    // run `this` through the Parent constructor function
    Parent.apply(this, arguments);
}
Child.prototype = Object.create(Parent.prototype);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.