नए

7

के बजाय Object.create() का उपयोग करके निजी सदस्यों के साथ ऑब्जेक्ट कैसे बनाएं, संपादित करें: मैंने इसे अंत में बर्गी के उत्तर से बाहर निकाला।नए

धन्यवाद बर्गी।

pubPrivExample = (function() { 
    return { 
     init : function() { 
      var private; 

      this.setPrivate = function (p) { 
       private = p; 
      }; 
      this.getPrivate = function() { 
       return private; 
      }; 
     }, 

     public : "This is public\n" 
    }; 
}()); 

var a; 

a = Object.create(pubPrivExample); 
a.init(); 
a.setPrivate("This is private"); 

document.write(a.getPrivate()); 

संपादित करें: ऐसा लगता है कि मेरे प्रश्न का उत्तर एक स्पर्शरेखा पर बंद है। मुझे वास्तव में एक कारखाने में दिलचस्पी नहीं है और वास्तव में इसका उपयोग नहीं किया जाएगा। मेरा सवाल निजी राज्य के बारे में है। बर्गी के उत्तरों और टिप्पणियों से मुझे लगता है कि मैं कुछ एक साथ खींच सकता हूं।

जारी रखा जाना करने के लिए ...

संपादित करें: Bergi नीचे सवाल का जवाब देने शुरू कर दिया है, लेकिन सबसे महत्वपूर्ण हिस्सा बाहर छोड़ दिया - निजी राज्य।

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

मूल: जावास्क्रिप्ट में new से बचने के लिए मेरी खोज ने मुझे एक असाधारण स्थान पर ले जाया है। मैं निजी ऑब्जेक्ट सदस्यों को चाहता हूं, लेकिन मैं छोड़ना नहीं चाहता हूं।

यहां कोड है।

var trackQueue = {}; 

trackQueue.factory = function() { 
    var that, queue; 
    that = this; 
    queue = []; 

    that.push = function (item) { 
     queue.push(item); 
    }; 

    that.work = function() { 
     document.write(queue + "<br />"); 
    }; 

    return { 
     work : that.work, 
     push : that.push 
    };   
}; 

var a = Object.create(trackQueue.factory()); 
a.push("a"); 
a.push("b"); 
a.push("c"); 

var b = Object.create(trackQueue.factory()); 
b.push("d"); 
b.push("e"); 
b.push("f"); 

a.work(); 
b.work(); 

और एक jsfiddle

http://jsfiddle.net/dsjbirch/Wj6cp/10/

चाहेंगे init एक और अधिक मुहावरेदार/उचित factory विधि के लिए नाम हो सकता है?

क्या यह पागल है?

दयालु रहें - जावास्क्रिप्ट मेरी पहली भाषा नहीं है।

+2

आप 'new' का उपयोग क्यों नहीं करना चाहते हैं? –

+1

डगलस क्रॉकफ़ोर्ड। – bluekeys

+2

यह दुर्भाग्यपूर्ण है। –

उत्तर

2

हाँ, प्रोटोटाइप पर एक init विधि एक अधिक उपयुक्त नाम हो सकता है:

var proto = { 
    init: function(args) { 
     // setting up private-scoped vars, 
     var example = args; 
     // privileged methods 
     this.accessPrivate = function(){ return example; }; 
     // and other stuff 
     this.public = 5; 
    }, 
    prop: "defaultvalue", 
    ... 
} 

var instance = Object.create(proto); 
instance.init(); 

हालांकि, वहाँ बिल्कुल कोई कारण नया कीवर्ड जोड़ते हैं जो सुंदर ढंग से जोड़ती है के साथ शास्त्रीय निर्माता का उपयोग नहीं है Object.create और init कॉल करें।

और ध्यान दें कि आप Object.create का उपयोग बिल्कुल उपयोग नहीं कर रहे हैं। आपका कारखाना पैटर्न (पूरी तरह से लागू वैध) अच्छी वस्तुओं को लौटाता है। प्रत्येक के लिए नई ऑब्जेक्ट्स बनाने की आवश्यकता नहीं है जो उनसे प्राप्त होता है। बस कार्य करें:

var instance = trackQueue.factory(); 

आप प्रणाली नाम "बनाने" की ध्वनि पसंद है, तो आप अपने कारखाने के लिए एक अधिक मुहावरेदार नाम का उपयोग हो सकता है:

trackQueueFactory.create = function(args) {...}; 

संपादित करें: अपने विचार गठबंधन करने के लिए प्रोटोटाइप विरासत के साथ कारखाना पैटर्न इतना गलत नहीं है। फिर भी, प्रोटो ऑब्जेक्ट जिसमें से सभी निर्मित वस्तुओं को प्राप्त करने की आवश्यकता है, के बजाय प्रत्येक आमंत्रण पर एक नया निर्माण करना।आपका कोड इस प्रकार दिखाई देंगे:

var factory = { 
    proto: { 
     ... 
    }, 
    create: function(args) { 
     var product = Object.create(this.proto); 
     // set up private vars scoped to the create function 
     // privileged methods 
     product.doSomethingSpecial = function(){ ... }; 
     // and other stuff 
    } 
}; 

var a = factory.create(...); 
+0

मैं आपके उदाहरण में init फ़ंक्शन में निजी स्कोप्ड वर्र्स कैसे सेट करूं? – bluekeys

+0

सामान्य के रूप में: var कीवर्ड या फ़ंक्शन घोषणाओं का उपयोग करें, और उन्हें init फ़ंक्शन में स्कॉप्ड किया जाएगा। – Bergi

2

मुझे लगता है कि यह एक स्पष्ट तरीका है अपनी आवश्यकताओं को प्राप्त करने के लिए है: यदि मैं गलत यह एक है नहीं कर रहा हूँ

var renato = personFactory(1, "Renato Gama", 25); 
console.log(renato.getName()); //logs "Renato Gama" 
renato.setName("Renato Mendonça da Gama"); 
console.log(renato.getName()); //logs "Renato Mendonça da Gama" 

:

var personFactory = function(id, name, age){ 
    var _id = id; 
    var _name = name; 
    var _age = age; 

    var personPrototype = { 
     getId: function(){ 
      return _id; 
     }, 
     setId: function(id){ 
      _id = id; 
     }, 
     getName: function(){ 
      return _name; 
     }, 
     setName: function(name){ 
      _name = name; 
     }, 
     getAge: function(){ 
      return _age; 
     }, 
     setAge: function(age){ 
      _age = age; 
     }, 
     work: function(){ 
      document.write(this.toString()); 
     }, 
     toString: function(){ 
      return "Id: " + _id + " - Name: " + _name + " - Age: " + _age; 
     } 
    }; 

    return Object.create(personPrototype); 
}; 

प्रयोग मॉड्यूल पैटर्न उपयोग करता है। एक अच्छे स्पष्टीकरण के लिए this post का संदर्भ लें। This विषय के बारे में भी एक अच्छी पोस्ट है।

+0

नहीं, आप गलत हैं। आपने ओपी के समान त्रुटि की है: निजी-स्कोप-फैक्टर ऑब्जेक्ट्स पर ऑब्जेक्ट.क्रेट का उपयोग करने की बिल्कुल आवश्यकता नहीं है। – Bergi

+0

मुझे आपका अंक नहीं मिल सकता है, क्या आप थोड़ा सा स्पष्टीकरण दे सकते हैं? यह नहीं देख सकता कि इसे एक त्रुटि क्यों माना जाता है। मैं आपके दूसरे कोड ब्लॉक को भी लिखता हूं जैसा कि मैंने लिखा था, इस तथ्य पर भिन्नता है कि आपका प्रोटोटाइप फैक्ट्री का सार्वजनिक सदस्य है। यदि आपके कारखाने के ऑब्जेक्ट में अधिक सार्वजनिक कार्य होंगे लेकिन निर्माण() एक होगा तो मैं आपके दृष्टिकोण से सहमत हूं। – renatoargh

+0

आप ऑब्जेक्ट शाब्दिक ("personPrototype") को सीधे क्यों नहीं लौटते? आपके कोड में ऑब्जेक्ट.क्रेट का क्या उपयोग है? – Bergi

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