@ Loganfsmyth के उत्तर पर विस्तार करने के लिए:
जावास्क्रिप्ट में केवल सही मायने में निजी डेटा अभी भी scoped चर है। आपके पास निजी संपत्तियां नहीं हो सकती हैं जो कि सार्वजनिक संपत्तियों की तरह ही आंतरिक रूप से एक्सेस की गई हैं, लेकिन आप निजी डेटा को स्टोर करने के लिए स्कोप किए गए चर का उपयोग कर सकते हैं।
बंद चर
यहां का दृष्टिकोण निजी डेटा को स्टोर करने के लिए कंस्ट्रक्टर फ़ंक्शन के दायरे का उपयोग करना है, जो निजी है। इस निजी डेटा तक पहुंचने के तरीकों के लिए उन्हें निर्माणकर्ता के भीतर भी बनाया जाना चाहिए, जिसका अर्थ है कि आप उन्हें हर उदाहरण के साथ फिर से बना रहे हैं। यह एक प्रदर्शन और स्मृति दंड है, लेकिन कुछ का मानना है कि जुर्माना स्वीकार्य है। उन तरीकों के लिए दंड से बचा जा सकता है, जिन्हें सामान्य रूप से प्रोटोटाइप में जोड़कर निजी डेटा तक पहुंच की आवश्यकता नहीं है।
उदाहरण:
function Person(name) {
let age = 20; // this is private
this.name = name; // this is public
this.greet = function () {
// here we can access both name and age
console.log(`name: ${this.name}, age: ${age}`);
};
}
let joe = new Person('Joe');
joe.greet();
// here we can access name but not age
स्कोप कमजोर
पिछले दृष्टिकोण के प्रदर्शन और मेमोरी पेनल्टी से बचने के लिए WeakMap का उपयोग किया जा सकता है। WeakMaps वस्तुओं (यहां, उदाहरणों) के साथ डेटा को इस तरह से जोड़ता है कि इसे केवल उस WeakMap का उपयोग करके एक्सेस किया जा सकता है। इसलिए, हम निजी WeakMap बनाने के लिए scoped चर विधि का उपयोग करते हैं, फिर उस WeakMap का उपयोग निजी डेटा से संबंधित करने के लिए करते हैंthis
। यह स्कोप्ड वैरिएबल विधि से अधिक तेज़ है क्योंकि आपके सभी इंस्टेंसेस एक सिंगल वेकपेज़ को साझा कर सकते हैं, इसलिए आपको केवल अपने खुद के WeakMaps का उपयोग करने के लिए तरीकों को फिर से बनाने की आवश्यकता नहीं है।
उदाहरण:
let Person = (function () {
let privateProps = new WeakMap();
class Person {
constructor(name) {
this.name = name; // this is public
privateProps.set(this, {age: 20}); // this is private
}
greet() {
// Here we can access both name and age
console.log(`name: ${this.name}, age: ${privateProps.get(this).age}`);
}
}
return Person;
})();
let joe = new Person('Joe');
joe.greet();
// here we can access joe's name but not age
यह उदाहरण कई निजी संपत्तियों के लिए एक WeakMap का उपयोग करने के लिए ऑब्जेक्ट का उपयोग करता है; आप कई WeakMaps का उपयोग कर सकते हैं और उनका उपयोग कर सकते हैं age.set(this, 20)
, या एक छोटा आवरण लिख सकते हैं और इसे किसी अन्य तरीके से उपयोग कर सकते हैं, जैसेprivateProps.set(this, 'age', 0)
।
इस दृष्टिकोण की गोपनीयता सैद्धांतिक रूप से वैश्विक के साथ छेड़छाड़ करके भंग हो सकती है WeakMap
वस्तु के । उस ने कहा, सभी जावास्क्रिप्ट को मैंगल्ड ग्लोबल्स द्वारा तोड़ा जा सकता है। हमारा कोड पहले से ही इस धारणा पर बना है कि ऐसा नहीं हो रहा है।
(इस विधि के साथ भी किया जा सकता है Map
, लेकिन WeakMap
बेहतर है क्योंकि Map
मेमोरी लीक तब तक बनेगी जब तक आप बहुत सावधान न हों, और इस उद्देश्य के लिए दोनों अलग-अलग नहीं हैं।)
आधा-उत्तर: प्रतीकात्मक चिह्न
एक प्रतीक एक आदिम मूल्य है जो एक संपत्ति के नाम के रूप में काम कर सकता है। आप निजी चिह्न बनाने के लिए स्कोप की गई परिवर्तनशील पद्धति का उपयोग कर सकते हैं, फिर निजी डेटा को यहां संग्रहीत कर सकते हैंthis[mySymbol]
।
इस पद्धति की गोपनीयता का उपयोग करके उल्लंघन किया जा सकता है Object.getOwnPropertySymbols
, लेकिन ऐसा करने के लिए कुछ अजीब है।
उदाहरण:
let Person = (function () {
let ageKey = Symbol();
class Person {
constructor(name) {
this.name = name; // this is public
this[ageKey] = 20; // this is intended to be private
}
greet() {
// Here we can access both name and age
console.log(`name: ${this.name}, age: ${this[ageKey]}`);
}
}
return Person;
})();
let joe = new Person('Joe');
joe.greet();
// Here we can access joe's name and, with a little effort, age. ageKey is
// not in scope, but we can obtain it by listing all Symbol properties on
// joe with `Object.getOwnPropertySymbols(joe)`.
अर्ध-उत्तर: अंडरस्कोर
पुराना डिफ़ॉल्ट, बस एक अंडरस्कोर उपसर्ग के साथ एक सार्वजनिक संपत्ति का उपयोग करें। हालांकि किसी भी तरह से एक निजी संपत्ति नहीं है, यह सम्मेलन पर्याप्त रूप से प्रचलित है कि यह एक अच्छा काम करता है जो यह बताता है कि पाठकों को निजी संपत्ति के रूप में व्यवहार करना चाहिए, जो अक्सर काम पूरा हो जाता है। इस चूक के बदले में, हमें एक दृष्टिकोण मिलता है जिसे पढ़ना आसान है, टाइप करना आसान है, और तेज है।
उदाहरण:
class Person {
constructor(name) {
this.name = name; // this is public
this._age = 20; // this is intended to be private
}
greet() {
// Here we can access both name and age
console.log(`name: ${this.name}, age: ${this._age}`);
}
}
let joe = new Person('Joe');
joe.greet();
// Here we can access both joe's name and age. But we know we aren't
// supposed to access his age, which just might stop us.
निष्कर्ष
ES2017 के अनुसार, निजी संपत्तियों को करने का कोई सही तरीका नहीं है। विभिन्न दृष्टिकोणों के पक्ष और विपक्ष हैं। स्कोप किए गए चर वास्तव में निजी हैं; स्कोप्ड WeakMaps स्कूप्ड वैरिएबल्स की तुलना में बहुत निजी और अधिक व्यावहारिक हैं; स्कोप किए गए प्रतीक यथोचित निजी और यथोचित व्यावहारिक हैं; अंडरस्कोर अक्सर पर्याप्त निजी और बहुत व्यावहारिक होते हैं।