दिलचस्प पोस्ट
रेज़र एचटीएमएल हेल्पर एक्सटेंशन (या अन्य नामस्थानों के लिए दृश्य) नहीं मिला क्या "glob" प्रकार पैटर्न के लिए java.util.regex का बराबर है? IPhone सिम्युलेटर में आईफ़ोन आवेदन कैसे स्थापित करें I पीएचपी के "वेरिएबल वैरिएबल" का उद्देश्य सी बराबर सूची दृश्य के लिए कस्टम एडाप्टर मैं खुली फ़ाइल में दो बार क्यों नहीं पढ़ सकता हूं? PHP (> = 5.0) में, संदर्भ से गुजर रहा है? फाइल से एक ही फ़ाइल में इनपुट को वापस दोहराएं क्या किसी Android एप्लिकेशन से रनटाइम पर गतिशील रूप से एक पुस्तकालय लोड करना संभव है? जावास्क्रिप्ट में ट्रिम स्ट्रिंग? हल करने में विफल: com.google.firebase: firebase-core: 11.2.0 टेक्स्टरिए में कर्सर स्थिति (वर्ण सूचकांक, x / y निर्देशांक नहीं) फोन नंबर स्वरूपण जब valueChangeListener या f का उपयोग करें: अजाक्स श्रोता? क्यों बराबर ऑपरेटर 128 अंक तक पूर्णांक मूल्य के लिए काम करता है?

विरासत के लिए `Object.create` का उपयोग करने के लाभ

मैं नए Object.create चारों ओर अपने सिर को लपेटने की कोशिश कर रहा हूं। Object.create विधि जिसे ECMAScript 5 में पेश किया गया था।

आम तौर पर जब मैं विरासत का इस्तेमाल करना चाहता हूं तो मैं ऐसा कुछ करता हूं:

 var Animal = function(name) { this.name = name; } Animal.prototype.print = function() { console.log(this.name); } var Dog = function() { return Animal.call(this, 'Dog'); } Dog.prototype = new Animal(); Dog.prototype.bark = function() { console.log('bark'); } 

मैं कुत्ते के प्रोटोटाइप के लिए एक नव निर्मित पशु वस्तु आवंटित करता हूं और सब कुछ एक जादू की तरह काम करता है:

 var dog1 = new Dog(); dog1.print(); // prints 'Dog' dog1.bark(); // prints 'bark' dog1.name; //prints 'Dog' 

लेकिन लोग (बिना समझाए हुए) कह रहे हैं कि Dog.prototype = new Animal(); जिस तरह से विरासत काम करता है और मुझे ऑब्जेक्ट का उपयोग करना चाहिए। बनाएँ दृष्टिकोण:

 Dog.prototype = Object.create(Animal.prototype); 

जो काम करता है

Object.create का उपयोग करने का क्या लाभ है। क्या मुझे कुछ याद आ रहा है?

अद्यतन: कुछ लोग कहते हैं कि Dog.prototype = Animal.prototype; काम भी कर सकते हैं तो अब मैं पूरी तरह से भ्रमित हूँ

वेब के समाधान से एकत्रित समाधान "विरासत के लिए `Object.create` का उपयोग करने के लाभ"

निम्नलिखित में मैं मानता हूं कि आप केवल रुचि रखते हैं, क्यों Object.create । विरासत विरासत को स्थापित करने के लिए बेहतर है।

लाभों को समझने के लिए, पहले स्पष्ट करें कि जावास्क्रिप्ट में "वर्ग" क्या बना है। आपके पास दो भाग हैं:

  1. कन्स्ट्रक्टर फ़ंक्शन। इस फ़ंक्शन में "क्लास" का उदाहरण बनाने के लिए सभी तर्क शामिल हैं, अर्थात उदाहरण विशिष्ट कोड

  2. प्रोटोटाइप ऑब्जेक्ट यह वह वस्तु है जो उदाहरण से इनहेरिट करता है इसमें सभी विधियों (और अन्य गुण) शामिल हैं जिन्हें सभी उदाहरणों में साझा किया जाना चाहिए।

विरासत एक संबंध स्थापित करता है , उदाहरण के लिए, एक Dog एक Animal कन्स्ट्रक्टर फ़ंक्शन और प्रोटोटाइप ऑब्जेक्ट के संदर्भ में यह कैसे व्यक्त किया जाता है?

जाहिर है, एक कुत्ते को जानवरों के समान ही तरीक़ा चाहिए, जो कि Dog प्रोटोटाइप ऑब्जेक्ट किसी भी तरह से Animal प्रोटोटाइप ऑब्जेक्ट से तरीकों को शामिल करना चाहिए। ऐसा करने के कई तरीके हैं आप अक्सर यह देखेंगे:

 Dog.prototype = new Animal(); 

यह काम करता है क्योंकि एक Animal उदाहरण Animal प्रोटोटाइप ऑब्जेक्ट से मिलता है। लेकिन इसका यह भी अर्थ है कि प्रत्येक कुत्ते को एक विशिष्ट Animal उदाहरण से मिलता है यह थोड़ा अजीब लगता है उदाहरण के लिए विशिष्ट कोड केवल कन्स्ट्रक्टर फ़ंक्शन में चलना चाहिए? अचानक विशिष्ट कोड और प्रोटोटाइप के तरीकों को मिश्रित लगता है।

हम वास्तव में उस समय Animal उदाहरण विशिष्ट कोड को चलाने के लिए नहीं चाहते, हम केवल Animal प्रोटोटाइप ऑब्जेक्ट से सभी तरीकों चाहते हैं। यह Object.create क्या है। Object.create हमें यह करने की सुविधा देता है:

 Dog.prototype = Object.create(Animal.prototype); 

यहाँ हम एक नया Animal उदाहरण नहीं बना रहे हैं, हम केवल प्रोटोटाइप तरीकों को प्राप्त करते हैं। उदाहरण विशिष्ट कोड को ठीक उसी प्रकार निष्पादित किया जाता है, जहां कन्स्ट्रक्टर के अंदर होना चाहिए:

 function Dog() { Animal.call(this, 'Dog'); } 

सबसे बड़ा फायदा यह है कि Object.create हमेशा काम करेगा। new Animal() का उपयोग केवल अगर कन्स्ट्रक्टर किसी भी तर्क की अपेक्षा नहीं करता है, तो काम करता है। कल्पना कीजिए कि निर्माता इस तरह दिखता है:

 function Animal(name) { this.name = name.toLowerCase(); } 

आपको हमेशा Animal को एक स्ट्रिंग देना होगा, अन्यथा आपको एक त्रुटि मिल जाएगी जब आप Dog.prototype = new Animal(??); करते हैं तो आप क्या करेंगे। Dog.prototype = new Animal(??); ? यह वास्तव में कोई फर्क नहीं पड़ता कि आप जिस स्ट्रिंग को पास करते हैं, जब तक कि कुछ गुजरता है , जो उम्मीद करता है कि यह खराब डिजाइन है


कुछ लोग कहते हैं कि Dog.prototype = Animal.prototype; काम भी कर सकते हैं तो अब मैं पूरी तरह से भ्रमित हूँ

जो चीज Animal.prototype से Animal.prototype के गुणों को जोड़ती है, वह सब कुछ "काम" करेगा। लेकिन समाधान विभिन्न गुणवत्ता के हैं इस मामले में यहां आपको समस्या होगी कि किसी भी विधि को आप Dog.prototype जोड़ देंगे Dog.prototype में भी जोड़ा जाएगा।

उदाहरण:

 Dog.prototype.bark = function() { alert('bark'); }; 

चूंकि Dog.prototype === Animal.prototype , सभी Animal उदाहरणों में अब एक विधि bark है, जो निश्चित रूप से नहीं है जो आप चाहते हैं।

Object.create (और यहां तक ​​कि new Animal ) एक नया ऑब्जेक्ट बनाकर उत्तराधिकार के लिए एक तरह से Animal.prototype जो Animal.prototype से विरासत में Animal.prototype और वह नया ऑब्जेक्ट Dog.prototype हो जाता है।


ES6 में विरासत

ES6 कंस्ट्रक्टर फ़ंक्शंस और प्रोटोटाइप विधियों को बनाने के लिए एक नया सिंटैक्स पेश करता है, जो इस तरह दिखता है:

 class Dog extends Animal { bark() { alert('bark'); } } 

यह जो मैंने ऊपर समझाया है उससे अधिक सुविधाजनक है, लेकिन जैसा कि यह पता चला है, extends भी आंतरिक Object.create लिए एक आंतरिक Object.create का उपयोग करता है। सेटअप विरासत को Object.create ES6 मसौदे में चरण 2 और 3 देखें।
जिसका अर्थ है कि Object.create(SuperClass.prototype) का उपयोग Object.create(SuperClass.prototype) में "अधिक सही" दृष्टिकोण है।

सबसे पहले, Animal निर्माता के चलने के अवांछित दुष्प्रभाव हो सकते हैं। इस पर विचार करो:

 var Animal = function(name) { this.name = name; Animal.instances.push(this); }; Animal.instances = []; 

यह संस्करण सभी उदाहरणों का ट्रैक रखता है जो बनाए गए हैं। आप नहीं चाहते कि आपके Dog.prototypeDog.prototype को वहां दर्ज किया जाए।

दूसरा, Dog.prototype = Animal.prototype एक बुरा विचार है, क्योंकि इसका मतलब होगा कि bark Animal की एक विधि बन जाएगा।

मैं थोड़ा अंतर अंतराने की कोशिश कर रहा हूँ:

यहां मूल रूप से क्या होता है जब आप new Animal() लिखते हैं new Animal() :

  //creating a new object var res = {}; //setting the internal [[prototype]] property to the prototype of Animal if (typeof Animal.prototype === "object" && Animal.prototype !== null) { res.__proto__ = Animal.prototype; } //calling Animal with the new created object as this var ret = Animal.apply(res, arguments); //returning the result of the Animal call if it is an object if (typeof ret === "object" && ret !== null) { return ret; } //otherise return the new created object return res; 

और यहाँ मूल रूप से Object.create साथ होता है। Object.create :

  //creating a new object var res = {}; //setting the internal [[prototype]] property to the prototype of Animal if (typeof Animal.prototype !== "object") { throw "...."; } res.__proto__ = Animal.prototype; //return the new created object return res; 

तो यह वही करता है, लेकिन यह Animal समारोह को कॉल नहीं करता है और यह हमेशा नए निर्मित ऑब्जेक्ट देता है आपके मामले में आप दो अलग-अलग वस्तुओं के साथ समाप्त होते हैं। पहली विधि के साथ आपको मिलती है:

 Dog.prototype = { name: undefined, __proto__: Animal.prototype }; 

और दूसरी विधि के साथ आपको मिलती है:

 Dog.prototype = { __proto__: Animal.prototype }; 

आप वास्तव में अपने प्रोटोटाइप में name संपत्ति की आवश्यकता नहीं है, क्योंकि आप पहले से ही Animal.call(this, 'Dog'); साथ अपने Dog उदाहरण के लिए निर्दिष्ट है Animal.call(this, 'Dog');

आपका प्राथमिक लक्ष्य अपने Dog उदाहरण को Animal प्रोटोटाइप के सभी गुणों का उपयोग करना है, जो दोनों विधियों द्वारा प्राप्त किया जाता है। पहला तरीका हालांकि कुछ अतिरिक्त चीजें हैं जो वास्तव में आपके मामले में जरूरी नहीं हैं या अवांछित परिणाम भी पैदा कर सकते हैं जैसा कि Pumbaa80 ने उल्लेख किया है।

चलो इसे केवल कोड के साथ समझें;

एप्रोटाटिप = बीप्रोटोटाइप;

 function B() {console.log("I am B");this.b1= 30;} B.prototype.b2 = 40; function A() {console.log("I am A");this.a1= 10;} A.prototype.a2 = 20; A.prototype = B.prototype; A.prototype.constructor = A; var a = new A; var b = new B; console.log(a);//A {a1: 10, b2: 40} console.log(b);//B {b1: 30, b2: 40} console.log(A.prototype.constructor);//A console.log(B.prototype.constructor);//A console.log(A.prototype);//A {b2: 40} console.log(B.prototype);//A {b2: 40} console.log(a.constructor === A); //true console.log(b.constructor === A); //true console.log(a.a2);//undefined 

यहां छवि विवरण दर्ज करें

एप्रोटोटाइप = ऑब्जेक्ट। बनाएं (बीप्रोटोटाइप);

 function B() {console.log("I am B");this.b1= 30;} B.prototype.b2 = 40; function A() {console.log("I am A");this.a1= 10;} A.prototype.a2 = 20; A.prototype = Object.create(B.prototype); A.prototype.constructor = A; var a = new A; var b = new B; console.log(a);//A {a1: 10, constructor: function, b2: 40} console.log(b);//B {b1: 30, b2: 40} console.log(A.prototype.constructor);//A console.log(B.prototype.constructor);//B console.log(A.prototype);//A {constructor: function, b2: 40} console.log(B.prototype);//B {b2: 40} console.log(a.constructor === A); //true console.log(b.constructor === B); //true console.log(a.a2);//undefined 

यहां छवि विवरण दर्ज करें