दिलचस्प पोस्ट
उद्देश्य-सी – एएपीएशन के बाद परिवर्तन लागू करने वाले सीएबीएसिक एनीमेशन? ASP.NET C # में ईमेल कैसे भेजें IntelliJ और टोमट .. कैसे ..? SQL सर्वर में किसी VARCHAR से गैर-संख्यात्मक वर्ण निकालने का सबसे तेज़ तरीका कन्वर्ट यूटीसी समयक्षेत्र या तारीख को ऑफसेट WPF बाइंडिंग का उपयोग करके दो कमांड पैरामीटर पास करना पैडिंग और बॉर्डर बॉक्स में फ्लेक्स-सिकुड़ कारक कैसे होता है? पायथन: अमान्य टोकन स्विंग और एडब्ल्यूटी के बीच अंतर क्या है? छवि शेयर का उद्देश्य जीमेल के लिए काम करता है लेकिन एफबी और ट्विटर को क्रैश करता है टैब पृष्ठ हेडर रंग सेट करें डिज्स्स्ट्रा के एल्गोरिथम का उपयोग करने वाले नकारात्मक भार स्विंग में गतिशील जीयूआई कैसे कार्यान्वित करें यूआरएल सांकेतिक शब्दों में कहें "और" (एम्परसेंड) को "& amp;" एचटीएमएल इकाई के रूप में देखता है माइग्रेशन: लार्वेल में विदेशी कुंजी बाधा नहीं जोड़ सकते

जावास्क्रिप्ट ईएस 6 कक्षाओं में निजी संपत्तियां

क्या ईएस 6 वर्गों में निजी संपत्तियां बनाना संभव है?

यहाँ एक उदाहरण है instance.property लिए मैं कैसे पहुंच रोक सकता हूं। instance.property ?

 class Something { constructor(){ this.property = "test"; } } var instance = new Something(); console.log(instance.property); //=> "test" 

वेब के समाधान से एकत्रित समाधान "जावास्क्रिप्ट ईएस 6 कक्षाओं में निजी संपत्तियां"

लघु उत्तर, नहीं, ES6 वर्गों के साथ निजी संपत्तियों के लिए कोई देशी समर्थन नहीं है।

लेकिन आप उस प्रथा की नकल कर नए गुणों को ऑब्जेक्ट में संलग्न नहीं कर सकते, बल्कि उन्हें एक क्लास कन्स्ट्रक्टर के अंदर रख सकते हैं, और छिपे हुए गुणों तक पहुंचने के लिए गेटर्स और सेटर्स का उपयोग कर सकते हैं। ध्यान दें कि गेटर्स और सेटर्स को कक्षा के प्रत्येक नए उदाहरण पर पुनः परिभाषित किया जाता है।

ES6

 class person { constructor(name) { var _name = name this.setName = function(name) { _name = name; } this.getName = function() { return _name; } } } 

ES5

 function person(name) { var _name = name this.setName = function(name) { _name = name; } this.getName = function() { return _name; } } 

अद्यतन: अच्छे सिंटैक्स के साथ एक प्रस्ताव अपने रास्ते पर है। योगदान स्वागत है


हां, वहां है – ऑब्जेक्ट्स में स्कॉड एक्सेस के लिए – ईएस 6 Symbol एस को प्रस्तुत करता है ।

प्रतीकों अद्वितीय हैं, आप प्रतिबिंब के अलावा बाहर से एक तक पहुंच प्राप्त नहीं कर सकते हैं (जैसे कि जावा / सी # में निजी) लेकिन किसी भी व्यक्ति को अंदर के प्रतीक का उपयोग करने के लिए इसका मुख्य उपयोग के लिए उपयोग किया जा सकता है:

 var property = Symbol(); class Something { constructor(){ this[property] = "test"; } } var instance = new Something(); console.log(instance.property); //=> undefined, can only access with access to the Symbol 

@ Loganfsmyth के उत्तर पर विस्तार करने के लिए:

जावास्क्रिप्ट में केवल सचमुच निजी डेटा अभी भी चर डाला गया है निजी संपत्तियों को निजी संपत्तियों के रूप में सार्वजनिक संपत्तियों के समान आंतरिक रूप से एक्सेस किए जाने के संदर्भ में नहीं हो सकते, लेकिन आप निजी डेटा को स्टोर करने के लिए स्कॉपी चर का उपयोग कर सकते हैं।

स्कॉन्डेड वैरिएबल

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

उदाहरण:

 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 बनाने के लिए स्कॉक्ड वैरिएबल विधि का उपयोग करते हैं, फिर उस से जुड़े निजी डेटा को पुनर्प्राप्त करने के लिए WeakMap का उपयोग this । यह स्कॉड वैरिएबल विधि से अधिक तेज़ है क्योंकि आपके सभी इंस्टेंस एक ही वीकमैप को साझा कर सकते हैं, इसलिए आपको अपने खुद के वीकमैप्स तक पहुंच बनाने के तरीकों को फिर से बनाने की आवश्यकता नहीं है।

उदाहरण:

 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 का उपयोग करने के लिए एक ऑब्जेक्ट का उपयोग करता है; आप भी कई कमजोरों का उपयोग कर सकते हैं और उन्हें age.set(this, 20) तरह इस्तेमाल कर सकते age.set(this, 20) , या एक छोटे से आवरण लिखें और इसे दूसरे तरीके से उपयोग age.set(this, 20) जैसे age.set(this, 20) privateProps.set(this, 'age', 0)

इस दृष्टिकोण की गोपनीयता वैश्विक WeakMap ऑब्जेक्ट के साथ छेड़छाड़ से सैद्धांतिक रूप से भंग हो सकती है। उस ने कहा, सभी जावास्क्रिप्ट मैंगल ग्लोबल द्वारा तोड़ा जा सकता है। हमारा कोड पहले से ही धारणा पर बनाया गया है कि ऐसा नहीं हो रहा है।

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

आधा-उत्तर: स्कॉच प्रतीक

एक प्रतीक प्राचीन मूल्य का एक प्रकार है जो संपत्ति के नाम के रूप में सेवा कर सकता है। आप एक निजी प्रतीक बनाने के लिए this[mySymbol] चर विधि का उपयोग कर सकते हैं, फिर this[mySymbol] निजी डेटा संग्रहीत 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 के अनुसार, अभी भी निजी संपत्तियों का कोई भी सही तरीका नहीं है। विभिन्न तरीकों के पास पेशेवर और विपक्ष हैं Scoped चर वास्तव में निजी हैं; स्कॉक्ड वेरिएबल्स की तुलना में कमजोर नजरअंदाज बहुत निजी और अधिक व्यावहारिक हैं; स्कॉन्ड चिन्ह उचित रूप से निजी और यथोचित व्यावहारिक हैं; अंडरस्कोर अक्सर प्रायः पर्याप्त और बहुत ही व्यावहारिक रूप से निजी होते हैं।

जवाब न है"। लेकिन आप इस तरह से संपत्तियों तक निजी पहुंच बना सकते हैं:

  • मॉड्यूल का उपयोग करें एक मॉड्यूल में सब कुछ निजी है जब तक यह export कीवर्ड का उपयोग करके सार्वजनिक नहीं हो।
  • मॉड्यूल के अंदर फ़ंक्शन समापन का उपयोग करें: http://www.kirupa.com/html5/closures_in_javascript.htm

(सुझाव है कि गोपनीयता का उपयोग सुनिश्चित करने के लिए प्रतीक का उपयोग ईएस 6 स्पेक के पहले संस्करण में सही था लेकिन अब यह मामला नहीं है: https://mail.mozilla.org/pipermail/es-discuss/2014- Januaryuary/035604 । HTML और https://stackoverflow.com/a/22280202/1282216 । प्रतीक और गोपनीयता के बारे में अधिक चर्चा के लिए देखें: https://curiosity-driven.org/private-properties-in-javascript )

जेएस में सच्ची गोपनीयता पाने का एकमात्र तरीका स्क्रॉपिंग के माध्यम से है, इसलिए संपत्ति का कोई रास्ता नहीं है जो कि इसका सदस्य है जो केवल घटक के भीतर ही पहुंच योग्य होगा। ES6 में वास्तव में निजी डेटा को स्टोर करने का सबसे अच्छा तरीका है WeakMap के साथ।

 const privateProp1 = new WeakMap(); const privateProp2 = new WeakMap(); class SomeClass { constructor() { privateProp1.set(this, "I am Private1"); privateProp2.set(this, "I am Private2"); this.publicVar = "I am public"; this.publicMethod = () => { console.log(privateProp1.get(this), privateProp2.get(this)) }; } printPrivate() { console.log(privateProp1.get(this)); } } 

जाहिर है यह शायद धीमी और निश्चित रूप से बदसूरत है, लेकिन यह गोपनीयता प्रदान करता है

ध्यान रखें कि यह भी सही नहीं है, क्योंकि जावास्क्रिप्ट बहुत गतिशील है कोई भी अभी भी कर सकता है

 var oldSet = WeakMap.prototype.set; WeakMap.prototype.set = function(key, value){ // Store 'this', 'key', and 'value' return oldSet.call(this, key, value); }; 

मूल्यों को पकड़ने के लिए जैसे वे जमा किए जाते हैं, इसलिए यदि आप अतिरिक्त सावधान रहना चाहते हैं, तो आप को स्थानीय संदर्भ पर कब्जा करने की आवश्यकता है। .set और .set प्रोटोटाइप पर भरोसा करने के बजाय स्पष्ट रूप से उपयोग करें।

 const {set: WMSet, get: WMGet} = WeakMap.prototype; const privateProp1 = new WeakMap(); const privateProp2 = new WeakMap(); class SomeClass { constructor() { WMSet.call(privateProp1, this, "I am Private1"); WMSet.call(privateProp2, this, "I am Private2"); this.publicVar = "I am public"; this.publicMethod = () => { console.log(WMGet.call(privateProp1, this), WMGet.call(privateProp2, this)) }; } printPrivate() { console.log(WMGet.call(privateProp1, this)); } } 

भविष्य में अन्य लोगों के भविष्य के संदर्भ में, मैं अब सुन रहा हूं कि निजी डेटा को पकड़ने के लिए कमजोर मैप का इस्तेमाल करना सिफारिश है।

यहां एक अधिक स्पष्ट, काम करने वाला उदाहरण है:

 function storePrivateProperties(a, b, c, d) { let privateData = new WeakMap; // unique object as key, weak map can only accept object as key, when key is no longer referened, garbage collector claims the key-value let keyA = {}, keyB = {}, keyC = {}, keyD = {}; privateData.set(keyA, a); privateData.set(keyB, b); privateData.set(keyC, c); privateData.set(keyD, d); return { logPrivateKey(key) { switch(key) { case "a": console.log(privateData.get(keyA)); break; case "b": console.log(privateData.get(keyB)); break; case "c": console.log(privateData.get(keyC)); break; case "d": console.log(privateData.set(keyD)); break; default: console.log(`There is no value for ${key}`) } } } } 

निर्भर करता है कि आप किससे पूछते हैं 🙂

कोई भी private संपत्ति संशोधक अधिकतम न्यूनतम कक्षा प्रस्ताव में शामिल नहीं है जो इसे वर्तमान मसौदे में बना दिया है।

हालांकि, निजी नामों के लिए समर्थन हो सकता है, जो निजी संपत्तियों को अनुमति देता है – और संभवतः वे कक्षा परिभाषाओं में भी इस्तेमाल किए जा सकते हैं

@ डी 13 को पूरा करना और @ जॉनी-ओशिका और @DanyalAytekin द्वारा टिप्पणियां:

मुझे लगता है कि @ जॉनी-ओशिका द्वारा प्रदान किए गए उदाहरण में हम तीर फ़ंक्शन के बजाय सामान्य फ़ंक्शन का उपयोग कर सकते हैं और फिर उन्हें वर्तमान ऑब्जेक्ट के साथ और क्यूड पैरामीटर के रूप में एक _

something.js

 function _greet(_privates) { return 'Hello ' + _privates.message; } function _updateMessage(_privates, newMessage) { _privates.message = newMessage; } export default class Something { constructor(message) { const _privates = { message }; this.say = _greet.bind(this, _privates); this.updateMessage = _updateMessage.bind(this, _privates); } } 

main.js

 import Something from './something.js'; const something = new Something('Sunny day!'); const message1 = something.say(); something.updateMessage('Cloudy day!'); const message2 = something.say(); console.log(message1 === 'Hello Sunny day!'); // true console.log(message2 === 'Hello Cloudy day!'); // true // the followings are not public console.log(something._greet === undefined); // true console.log(something._privates === undefined); // true console.log(something._updateMessage === undefined); // true // another instance which doesn't share the _privates const something2 = new Something('another Sunny day!'); const message3 = something2.say(); console.log(message3 === 'Hello another Sunny day!'); // true 

लाभ मैं सोच सकता हूँ:

  • हम निजी तरीकों ( _greet और _updateMessage कार्य कर सकते हैं निजी विधियों की तरह जब तक हम संदर्भ export नहीं करते हैं)
  • हालांकि वे प्रोटोटाइप पर नहीं हैं, उपर्युक्त विधियों मेमोरी बचाएगी क्योंकि उदाहरणों को एक बार क्लास के बाहर बनाया जाता है (जैसा कि उन्हें कन्स्ट्रक्टर में परिभाषित करने का विरोध किया गया)
  • हम किसी भी ग्लोबल रिसाव नहीं करते क्योंकि हम एक मॉड्यूल के अंदर हैं
  • हम बाँध किए गए _privates ऑब्जेक्ट का उपयोग करके निजी संपत्ति भी कर सकते हैं

कुछ कमियां जो मैं सोच सकता हूँ:

  • कम सहज ज्ञान युक्त
  • क्लास सिंटैक्स और पुराने स्कूल पैटर्न (ऑब्जेक्ट बाइंडिंग, मॉड्यूल / फंक्शन स्कॉप्स चर) के मिश्रित उपयोग
  • हार्ड बाइंडिंग – हम सार्वजनिक विधियों को रिबिल्ट नहीं कर सकते (हालांकि हम सॉफ्ट बाइंडिंग का उपयोग करके इसे सुधार सकते हैं ( https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26% 20object% 20prototypes / ch2.md # नरम-बाध्यकारी ))

चलने वाला स्निपेट यहां पाया जा सकता है: http://www.webpackbin.com/NJgI5J8lZ

ES6 मॉड्यूल का प्रयोग (शुरुआत में @ डी 13 द्वारा प्रस्तावित) मेरे लिए अच्छी तरह से काम करता है यह पूरी तरह से निजी संपत्ति की नकल नहीं करता है, लेकिन कम से कम आप यह आश्वस्त हो सकते हैं कि संपत्ति जो निजी होनी चाहिए, वह आपकी कक्षा से बाहर नहीं निकलेगी। यहां एक उदाहरण है:

something.js

 let _message = null; const _greet = name => { console.log('Hello ' + name); }; export default class Something { constructor(message) { _message = message; } say() { console.log(_message); _greet('Bob'); } }; 

फिर उपभोक्ता कोड इस तरह दिख सकता है:

 import Something from './something.js'; const something = new Something('Sunny day!'); something.say(); something._message; // undefined something._greet(); // exception 

अपडेट (महत्वपूर्ण):

टिप्पणियों में बताए गए @ डायनाल एटेकिन के रूप में, ये निजी गुण स्थिर हैं, इसलिए वैश्विक रूप से क्षेत्रफल। Singletons के साथ काम करते समय वे अच्छी तरह से काम करेंगे, लेकिन क्षणिक वस्तुओं के लिए देखभाल की जानी चाहिए ऊपर दिए गए उदाहरण को बढ़ाते हुए:

 import Something from './something.js'; import Something2 from './something.js'; const a = new Something('a'); a.say(); // a const b = new Something('b'); a.say(); // a const c = new Something2('c'); c.say(); // c a.say(); // c b.say(); // c c.say(); // c 

हाँ – आप इनकॉप्लेटेड प्रॉपर्टी बना सकते हैं , लेकिन यह कम से कम ईएस 6 के साथ एक्सेस मॉडिफ़ियर्स (पब्लिक | प्राइवेट) के साथ नहीं किया गया है।

यह एक साधारण उदाहरण है कि यह ES6 के साथ कैसे किया जा सकता है:

1 कक्षा शब्द का उपयोग करके कक्षा बनाएं

2 इसके अंदर कंस्ट्रक्टर ब्लॉक-स्कॉक्स्ड व्हेरिएबल को घोषित करते हैं या आरक्षित आरक्षित शब्द -> चूंकि वे ब्लॉक-स्कोप हैं वे बाहर (एन्कैप्लेटेड) से एक्सेस नहीं कर सकते हैं

3 उन चर के लिए कुछ एक्सेस कंट्रोल (सेटर्स | गेटर्स) को अनुमति देने के लिए आप इसके निर्माता के भीतर उदाहरण विधि घोषित कर सकते हैं: this.methodName=function(){} syntax

 "use strict"; class Something{ constructor(){ //private property let property="test"; //private final (immutable) property const property2="test2"; //public getter this.getProperty2=function(){ return property2; } //public getter this.getProperty=function(){ return property; } //public setter this.setProperty=function(prop){ property=prop; } } } 

अब इसे जांचने देता है:

 var s=new Something(); console.log(typeof s.property);//undefined s.setProperty("another");//set to encapsulated `property` console.log(s.getProperty());//get encapsulated `property` value console.log(s.getProperty2());//get encapsulated immutable `property2` value 

मेरा मानना ​​है कि कन्स्ट्रक्टरों के अंदर क्लोजर का उपयोग करके 'दोनों दुनिया का सर्वश्रेष्ठ' मिलना संभव है। दो भिन्नरूप हैं:

सभी डेटा सदस्य निजी हैं

 function myFunc() { console.log('Value of x: ' + this.x); this.myPrivateFunc(); } function myPrivateFunc() { console.log('Enhanced value of x: ' + (this.x + 1)); } class Test { constructor() { let internal = { x : 2, }; internal.myPrivateFunc = myPrivateFunc.bind(internal); this.myFunc = myFunc.bind(internal); } }; 

वास्तव में यह प्रतीक और प्रॉक्सी का उपयोग कर संभव है। आप क्लास स्कोप में प्रतीकों का उपयोग करते हैं और प्रॉक्सी में दो जाल सेट करते हैं: एक क्लास प्रोटोटाइप के लिए ताकि Reflect.ownKeys (instance) या Object.getOwnPropertySymbols आपके प्रतीकों को दूर नहीं दे पाता है, अन्य एक ही कन्स्ट्रक्टर के लिए है इसलिए जब new ClassName(attrs) को बुलाया जाता है, तो लौटा दिया जाने वाला उदाहरण इंटरसेप्टेड हो जाएगा और उसके पास खुद के गुणचिह्नों को ब्लॉक किया जाएगा यहां कोड है:

 const Human = (function() { const pet = Symbol(); const greet = Symbol(); const Human = privatizeSymbolsInFn(function(name) { this.name = name; // public this[pet] = 'dog'; // private }); Human.prototype = privatizeSymbolsInObj({ [greet]() { // private return 'Hi there!'; }, revealSecrets() { console.log(this[greet]() + ` The pet is a ${this[pet]}`); } }); return Human; })(); const bob = new Human('Bob'); console.assert(bob instanceof Human); console.assert(Reflect.ownKeys(bob).length === 1) // only ['name'] console.assert(Reflect.ownKeys(Human.prototype).length === 1 ) // only ['revealSecrets'] // Setting up the traps inside proxies: function privatizeSymbolsInObj(target) { return new Proxy(target, { ownKeys: Object.getOwnPropertyNames }); } function privatizeSymbolsInFn(Class) { function construct(TargetClass, argsList) { const instance = new TargetClass(...argsList); return privatizeSymbolsInObj(instance); } return new Proxy(Class, { construct }); } 

निजी तौर पर मैं बाइंड ऑपरेटर का प्रस्ताव पसंद करता हूं और उसके बाद इसे @ डी 3 के समाधान के साथ गठबंधन किया जाएगा, लेकिन अब @ डी 13 के उत्तर के साथ चिपकाएं जहां आप अपने क्लास के लिए export कीवर्ड का उपयोग करते हैं और मॉड्यूल में निजी फ़ंक्शन डालते हैं।

वहाँ एक और समाधान कठिन है, जो यहां उल्लेख नहीं किया गया है कि इस प्रकार से अधिक कार्यात्मक दृष्टिकोण है और यह कक्षा में सभी निजी प्रारम्भ / विधियों को प्राप्त करने की अनुमति देगा।

Private.js

 export const get = state => key => state[key]; export const set = state => (key,value) => { state[key] = value; } 

Test.js

 import { get, set } from './utils/Private' export default class Test { constructor(initialState = {}) { const _set = this.set = set(initialState); const _get = this.get = get(initialState); this.set('privateMethod', () => _get('propValue')); } showProp() { return this.get('privateMethod')(); } } let one = new Test({ propValue: 5}); let two = new Test({ propValue: 8}); two.showProp(); // 8 one.showProp(); // 5 

इस पर टिप्पणी की सराहना होगी

"निजी" के लिए एक अलग दृष्टिकोण

इस तथ्य के खिलाफ लड़ने के बजाय कि निजी दृश्यता वर्तमान में ईएस 6 में अनुपलब्ध है, मैंने एक और व्यावहारिक दृष्टिकोण लेने का निर्णय लिया है जो आपकी IDE को JSDoc (जैसे, वेबस्टॉर्म) का समर्थन करता है। विचार @private टैग का उपयोग करना है जहां तक ​​विकास होता है, आईडीई आपको किसी भी निजी सदस्य को अपनी कक्षा के बाहर तक पहुंचने से रोकेगा। मेरे लिए बहुत अच्छी तरह से काम करता है और यह आंतरिक तरीकों को छिपाने के लिए वास्तव में उपयोगी रहा है ताकि स्वत: पूर्ण सुविधा मुझे दिखाती है कि क्लास वास्तव में क्या दिखाना है। यहां एक उदाहरण है:

केवल सार्वजनिक सामान को दिखाने वाला स्वत: पूर्ण

मुझे लगता है बेंजामिन का उत्तर ज्यादातर मामलों के लिए सबसे अच्छा है, जब तक कि भाषा मूल रूप से निजी चर का समर्थन नहीं करती।

हालांकि, यदि किसी कारण के लिए आपको Object.getOwnPropertySymbols() साथ पहुंच को रोकने की आवश्यकता है Object.getOwnPropertySymbols() , एक विधि जिसे मैंने उपयोग करने पर विचार किया है, एक अद्वितीय, गैर-कॉन्फ़िगर करने योग्य, गैर-एन्यूमेरेबल, गैर- Object.getOwnPropertySymbols() कर रहा है जिसे प्रॉपर्टी पहचानकर्ता के रूप में इस्तेमाल किया जा सकता है निर्माण पर प्रत्येक वस्तु के लिए (जैसे कि एक अद्वितीय Symbol , यदि आपके पास पहले से कोई अन्य अनूठी संपत्ति नहीं है जैसे id )। फिर उस आइडेंटिफ़ायर का उपयोग करके प्रत्येक ऑब्जेक्ट के 'निजी' वैरिएबल का मानचित्र रखें।

 const privateVars = {}; class Something { constructor(){ Object.defineProperty(this, '_sym', { configurable: false, enumerable: false, writable: false, value: Symbol() }); var myPrivateVars = { privateProperty: "I'm hidden" }; privateVars[this._sym] = myPrivateVars; this.property = "I'm public"; } getPrivateProperty() { return privateVars[this._sym].privateProperty; } } var instance = new Something(); console.log(instance.property); //=> "I'm public" console.log(instance.privateProperty); //=> undefined console.log(instance.getPrivateProperty()); //=> "I'm hidden" 

WeakMap का उपयोग करने के इस दृष्टिकोण का संभावित लाभ तेज पहुंच का समय है यदि प्रदर्शन चिंता का विषय बन जाता है

WeakMap

  • IE11 में समर्थित (प्रतीक नहीं हैं)
  • कठोर-निजी (प्रतीक का उपयोग करने के लिए Object.getOwnPropertySymbols कारण सॉफ्ट-प्राइवेट हैं। Object.getOwnPropertySymbols )
  • वास्तव में साफ दिख सकता है (समापन के विपरीत जो कन्स्ट्रक्टर में सभी प्रोप और तरीकों की आवश्यकता होती है)

सबसे पहले, WeakMap को लपेटने के लिए फ़ंक्शन परिभाषित करें:

 function Private() { const map = new WeakMap(); return obj => { let props = map.get(obj); if (!props) { props = {}; map.set(obj, props); } return props; }; } 

फिर, अपने वर्ग के बाहर एक संदर्भ बनाएं:

 const p = new Private(); class Person { constructor(name, age) { this.name = name; p(this).age = age; // it's easy to set a private variable } getAge() { return p(this).age; // and get a private variable } } 

नोट: वर्ग IE11 द्वारा समर्थित नहीं है, लेकिन यह उदाहरण में क्लीनर दिखता है।

 class Something { constructor(){ var _property = "test"; Object.defineProperty(this, "property", { get: function(){ return _property} }); } } var instance = new Something(); console.log(instance.property); //=> "test" instance.property = "can read from outside, but can't write"; console.log(instance.property); //=> "test" 

Coming very late to this party but I hit the OP question in a search so… Yes, you can have private properties by wrapping the class declaration in a closure

There is an example of how I have private methods in this codepen . In the snippet below, the Subscribable class has two 'private' functions process and processCallbacks . Any properties can be added in this manner and they are kept private through the use of the closure. IMO Privacy is a rare need if concerns are well separated and Javascript does not need to become bloated by adding more syntax when a closure neatly does the job.

 const Subscribable = (function(){ const process = (self, eventName, args) => { self.processing.set(eventName, setTimeout(() => processCallbacks(self, eventName, args)))}; const processCallbacks = (self, eventName, args) => { if (self.callingBack.get(eventName).length > 0){ const [nextCallback, ...callingBack] = self.callingBack.get(eventName); self.callingBack.set(eventName, callingBack); process(self, eventName, args); nextCallback(...args)} else { delete self.processing.delete(eventName)}}; return class { constructor(){ this.callingBack = new Map(); this.processing = new Map(); this.toCallbacks = new Map()} subscribe(eventName, callback){ const callbacks = this.unsubscribe(eventName, callback); this.toCallbacks.set(eventName, [...callbacks, callback]); return () => this.unsubscribe(eventName, callback)} // callable to unsubscribe for convenience unsubscribe(eventName, callback){ let callbacks = this.toCallbacks.get(eventName) || []; callbacks = callbacks.filter(subscribedCallback => subscribedCallback !== callback); if (callbacks.length > 0) { this.toCallbacks.set(eventName, callbacks)} else { this.toCallbacks.delete(eventName)} return callbacks} emit(eventName, ...args){ this.callingBack.set(eventName, this.toCallbacks.get(eventName) || []); if (!this.processing.has(eventName)){ process(this, eventName, args)}}}})(); 

I like this approach because it separates concerns nicely and keeps things truly private. The only downside is the need to use 'self' (or something similar) to refer to 'this' in the private content.

Even Typescript can't do it. From their documentation :

When a member is marked private, it cannot be accessed from outside of its containing class. उदाहरण के लिए:

 class Animal { private name: string; constructor(theName: string) { this.name = theName; } } new Animal("Cat").name; // Error: 'name' is private; 

But transpiled on their playground this gives:

 var Animal = (function () { function Animal(theName) { this.name = theName; } return Animal; }()); console.log(new Animal("Cat").name); 

So their "private" keyword is ineffective.

See this answer for aa clean & simple 'class' solution with a private and public interface and support for composition

Yes totally can, and pretty easily too. This is done by exposing your private variables and functions by returning the prototype object graph in the constructor. This is nothing new, but take a bit of js foo to understand the elegance of it. This way does not use global scoped, or weakmaps. It is a form of reflection built into the language. Depending on how you leverage this; one can either force an exception which interrupts the call stack, or bury the exception as an undefined . This is demonstarted below, and can read more about these features here

 class Clazz { constructor() { var _level = 1 function _private(x) { return _level * x; } return { level: _level, public: this.private, public2: function(x) { return _private(x); }, public3: function(x) { return _private(x) * this.public(x); }, }; } private(x) { return x * x; } } var clazz = new Clazz(); console.log(clazz._level); //undefined console.log(clazz._private); // undefined console.log(clazz.level); // 1 console.log(clazz.public(1)); //2 console.log(clazz.public2(2)); //2 console.log(clazz.public3(3)); //27 console.log(clazz.private(0)); //error 

Most answers either say it's impossible, or require you to use a WeakMap or Symbol, which are ES6 features that would probably require polyfills. There's however another way! Check out this out:

 // 1. Create closure var SomeClass = function() { // 2. Create `key` inside a closure var key = {}; // Function to create private storage var private = function() { var obj = {}; // return Function to access private storage using `key` return function(testkey) { if(key === testkey) return obj; // If `key` is wrong, then storage cannot be accessed console.error('Cannot access private properties'); return undefined; }; }; var SomeClass = function() { // 3. Create private storage this._ = private(); // 4. Access private storage using the `key` this._(key).priv_prop = 200; }; SomeClass.prototype.test = function() { console.log(this._(key).priv_prop); // Using property from prototype }; return SomeClass; }(); // Can access private property from within prototype var instance = new SomeClass(); instance.test(); // `200` logged // Cannot access private property from outside of the closure var wrong_key = {}; instance._(wrong_key); // undefined; error logged 

Actually it is possible.

 class Person{ constructor(name,age){ class Person{ constructor(_private){ this.name = name; this.age = age; this.isHuman = _private.human; this.greet = _private.greeting.call(this); //without 'call' it takes _private object as 'this' keyword } } //private properties here this.human = true; return new Person(this); } //private methods here greeting(){ return `hello ${this.name}`; } } var person = new Person('Paul',27); console.log(person.name); //'Paul' console.log(person.age); //27 console.log(person.isHuman); //true console.log(person.greet); //'Hello Paul' console.log(person.human); //undefined (private) console.log(person.greeting); //undefined (private) 

Another way similar to the last two posted

 class Example { constructor(foo) { // privates const self = this; this.foo = foo; // public interface return self.public; } public = { // empty data nodata: { data: [] }, // noop noop: () => {}, } // everything else private bar = 10 } const test = new Example('FOO'); console.log(test.foo); // undefined console.log(test.noop); // { data: [] } console.log(test.bar); // undefined