2009-01-12 3 views
11

यह एक प्रश्न का पालन है जिसे मैंने अभी पोस्ट किया है। मैं सोच रहा हूं कि विधियों को परिभाषित करने के लिए MyClass.prototype का उपयोग करते समय आप जावास्क्रिप्ट क्लॉज में सदस्य चर को कैसे प्रबंधित करते हैं।ऑब्जेक्ट उन्मुख जावास्क्रिप्ट में सदस्य चर के लिए सबसे अच्छा तरीका?

आप निर्माता समारोह में सभी विधियों को परिभाषित हैं:

function MyClass(){ 
this.myMethod = function(){} 
} 

तुम बहुत अच्छी तरह से सदस्य चर घोषित करने और अपने तरीके अंदर से उन तक पहुंच सकते हैं:

function MyClass(){ 
var myVar = "hello"; 
this.myMethod = function(){ 
    alert(myVar); 
} 
} 

वस्तु का उपयोग करते समय। प्रोटोटाइप तकनीक, आप इस निस्संदेह को खो देते हैं, और इसे इस तरह करना है;

function MyClass(){} 
MyClass.prototype.myVar = "hello"; 
MyClass.prototype.myMethod = function(){alert(this.hello)}; 

हर बार जब मैं सदस्य चर का उपयोग करता हूं तो मैं "यह" लिखने के बारे में पागल नहीं हूं। मैं स्मृति और लचीलापन कारणों के लिए ऑब्जेक्ट.प्रोटोटाइप दृष्टिकोण का उपयोग करना चाहता हूं, लेकिन ऐसा लगता है कि यह बहुत ही सुसंगत वाक्यविन्यास-वार है। क्या आप आम तौर पर काम करते हैं?

धन्यवाद,

-Morgan

+0

निजी विविधता के संबंध में ई सदस्य, आप Google क्लोजर कंपाइलर का उपयोग करने में रुचि ले सकते हैं। प्रत्येक वर्ग को एक अलग फ़ाइल में परिभाषित किया जा सकता है और निजी चर को संकलक द्वारा लागू किया जाएगा। https://developers.google.com/closure/compiler/docs/js-for-compiler#tag-private –

उत्तर

14

आप सदस्य चर का उपयोग करने के this सूचक का उपयोग करने के अपने घृणा से अधिक मिलना चाहिए।

निर्माता में असाइन सदस्य चर, और आप उन्हें प्रोटोटाइप तरीकों के साथ उपयोग कर सकते हैं:

function Cat(){ 
    this.legs = 4; 
    this.temperament = 'Apathetic'; 
    this.sound = 'Meow'; 
} 

Cat.prototype.speak = function(){alert(this.sound)} 

var cat = new Cat(); 
cat.speak(); 

हाँ उन वस्तु गुण सार्वजनिक कर रहे हैं लेकिन, के रूप में गुइडो कहेंगे, हम सभी वयस्कों यहाँ हो। जावास्क्रिप्ट, आखिरकार, एक सादे-पाठ, ढीले-टाइप की गई, व्याख्या की गई भाषा है। इस माहौल में "निजी" चर के लाभ सबसे अच्छे हैं।

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

+0

समस्या, निश्चित रूप से आपके पास निजी तरीके/वर्र्स नहीं हो सकते हैं। क्या आप कृपया इस तरह से पोस्ट कर सकते हैं कि आप प्रोटोटाइप विधि का उपयोग कर इसके लिए अनुमति दे सकते हैं? – nlaq

+0

ठीक है, ठीक है। मुझे लगता है मैं करूँगा। मैं अपने वर्र्स याद करने जा रहा हूं हालांकि :( – morgancodes

+1

@ नेल्सन - प्रोटोटाइप विधियों को "निजी चर" (वास्तव में, कन्स्ट्रक्टर के लिए स्थानीय चर) तक पहुंच नहीं होगी। मेरा जवाब यहां देखें: http://stackoverflow.com/questions/436120/जावास्क्रिप्ट-एक्सेसिंग-प्राइवेट-सदस्य-वेरिएबल्स-से-प्रोटोटाइप-डिफ़ाइंड-फ़ंक्शंस # 436147 – Triptych

3

क्योंकि जब आप अपने आप को 100 के तरीकों के साथ मिल जाए, वे उदाहरणों के बीच भर में इसकी नक़ल नहीं कर रहे हैं बल्कि वे एक ही प्रोटोटाइप का उपयोग आप, दुकान तरीकों के प्रोटोटाइप का उपयोग करना चाहिए। मैं इन पंक्तियों के साथ कुछ का उपयोग करें:

var myClass = function(){}; 
myClass.prototype = { 
    method1: function(){} 
    ,method2: function(){} 
}; 
+0

धन्यवाद sktrdie, यह एक प्रमुख कारण है कि मैं प्रोटोटाइप का उपयोग करने के लिए क्यों स्विच कर रहा हूं। मैं सोच रहा हूं कि सदस्य चर का प्रबंधन करने का सबसे अच्छा तरीका क्या है। क्या मुझे खुद को "यह" टाइप करने के लिए खुद को इस्तीफा देने की ज़रूरत है? – morgancodes

+0

पुन: "यह": हाँ, यह उन चीजों में से एक है जिसका उपयोग आपको अभी करना है। –

-2

आप अपने आप को भी शामिल है

function name() 
{ 
    var m_var = null; 
    var privateMethod = function() { } 
    this.PublicMethod = function() { } 
} 

का उपयोग कर बहुत से लोगों को मिल जाएगा। मैं विशाल जेएस कक्षाएं लिखना नहीं चाहता हूं और यह वाक्यविन्यास लिखना बहुत आसान है और निजी तरीकों/चर के लिए भी अनुमति देता है।

संपादित

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

हम्म ...

(मेरी एक्सएमएल टिप्पणी के लिए के लिए टिप्पणियां पढ़ें: REST URIs and operations on an object that can be commented on, tagged, rated, etc)

+0

-1। वह स्मृति लाभ के लिए प्रोटोटाइप कार्यों का उपयोग करना चाहता है, जो कभी-कभी पर्याप्त हो सकता है। – Triptych

+0

धन्यवाद नेल्सन, यही वह है जो मैंने हमेशा किया है, लेकिन हाल ही में यह पता चला है कि .इस विधि को प्रत्येक इंस्टेंस के लिए एक बार कॉपी किया जाएगा। कोई समस्या नहीं है यदि आपके पास केवल कुछ उदाहरण हैं, लेकिन यदि आपके पास बहुत कुछ है तो यह महत्वपूर्ण हो सकता है। – morgancodes

+0

एक और कारण मैं .prototype विधि का उपयोग करना चाहता था ताकि मैं वैकल्पिक रूप से एक विधि को ओवरराइड या विस्तार कर सकूं। अपने दृष्टिकोण का उपयोग करके, मुझे परिवर्तन करने के लिए तत्कालता के बाद तक इंतजार करना होगा। अगर मुझे इसके बारे में चिंता करने की ज़रूरत नहीं है तो अच्छा। – morgancodes

14

वस्तु की दृश्यता विशेषताओं के अनुसार बदलता रहता आप उन्हें कैसे घोषित

function Cat(name) { 

    //private variable unique to each instance of Cat 
    var privateName = 'Cat_'+Math.floor(Math.random() * 100); 

    //public variable unique to each instance of Cat 
    this.givenName = name; 

    //this method has access to private variables 
    this.sayPrivateName = function() { 
     alert(privateName); 
    } 
} 

//this variable is shared by all cats 
Cat.prototype.generalName = 'tiddles'; 

//this method is shared by all cats and has no access to private vars 
Cat.prototype.sayname = function(type) { 
    alert(this[type+'Name'] || 'private!'); 
} 

var vic = new Cat('Victor'); 
var ellers = new Cat('Elmore'); 

vic.sayname('general'); //tiddles 
vic.sayname('given');  //Victor 
vic.sayname('private'); //private - no access 
vic.sayPrivateName();  //cat will say its name 

ellers.sayname('general'); //tiddles 
ellers.sayname('given');  //Elmore 
ellers.sayname('private'); //private - no access 
ellers.sayPrivateName();  //cat will say its name 
+0

नोट: यदि आपका कन्स्ट्रक्टर कुछ भी (किसी ऑब्जेक्ट की तरह, कार्यों या मानों का पर्दाफाश करने के लिए) देता है तो आपके द्वारा 'इस' के साथ घोषित सभी सदस्यों को सार्वजनिक रूप से दिखाई नहीं दे रहा है। दूसरे शब्दों में, एक कन्स्ट्रक्टर में, या तो 'यह' से चिपके रहें या 'ऑब्जेक्ट' वापस करें - आम तौर पर दोनों नहीं करते हैं। – Matt

1

ए (नहीं तो) 'निजी' चर पर छोटे टिप्पणी जब प्रोटोटाइप तरीके बताए:

यह है कि आप सच है इसके चर पर बंद करने के लिए कन्स्ट्रक्टर का उपयोग नहीं कर सकते हैं, लेकिन आप निश्चित रूप से किसी अज्ञात फ़ंक्शन के साथ प्रोटोटाइपिकल विधियों को घेर सकते हैं और ऑब्जेक्ट के उदाहरणों के बीच निजी चर साझा कर सकते हैं:

function Foo() {} 

(function() { 
    var sharedPrivateVar; 
    Foo.prototype.methodWithAccessToSharedPrivateVar = function() {}; 
})(); 
कुछ आगे twiddling साथ

, आप अपने खुद के सुरक्षा तंत्र को लागू कर सकते, जैसे चर, केवल जो पढ़ा जा सकता है के माध्यम से नहीं लिखा:

function Foo() { 
    this.registerInstance({ bar : 'baz' }); 
    this.registerInstance = undefined; 
} 

(function() { 
    var store = {}, guid = 0; 

    Foo.prototype.registerInstance = function(protectedProperties) { 
     this.__guid = ++guid; 
     store[this.__guid] = protectedProperties; 
    }; 

    Foo.prototype.getProtectedProperty = function(name) { 
     return store[this.__guid][name]; 
    }; 

})(); 

यह दृष्टिकोण व्यापक समारोह वस्तु और बंद सृजन से ग्रस्त नहीं होगा, लेकिन एक छोटी राशि से लुकअप-टाइम्स बढ़ाता है।

संपादित करें: तुम भी आसपास पहुंच सकते हैं: तुम भी एक समारोह

Foo.prototype.unregisterInstance = function() { 
    delete store[this.__guid]; 
}; 

अन्यथा, यह एक स्मृति रिसाव शुरू करने की एक अच्छा तरीका है ...

EDIT2 प्रदान करना चाहिए निम्नलिखित पैटर्न के साथ registerInstance() फ़ंक्शन की आवश्यकता है:

Foo = (function() { 
    var store = {}, guid = 0; 

    function Foo() { 
     this.__guid = ++guid; 
     store[guid] = { bar : 'baz' }; 
    } 

    Foo.prototype.getBar = function() { 
     var privates = store[this.__guid]; 
     return privates.bar; 
    }; 

    Foo.prototype.destroy = function() { 
     delete store[this.__guid]; 
    }; 

    return Foo; 
})(); 
संबंधित मुद्दे