1

I have this private class attribiute and I want to change its value in prototyped method. But "privateVariable" is not visible in "increment" method. How can I access this attribute from this method?

var myClass = function(){
    var privateVariable = 1
}

myClass.prototype.increment=function(){
    privateVariable++
}

Mind you that it is a private attribute.

Bartek Kosa
  • 842
  • 1
  • 14
  • 25
  • You cannot. Notice that there are no classes, no attributes, and no privacy in JavaScript. You've got a *local variable* there. – Bergi Jan 22 '15 at 02:31
  • 2
    Maybe a better duplicate: http://stackoverflow.com/q/436120/218196 . @BartekKosa: Be nice. – Felix Kling Jan 22 '15 at 02:44
  • @Felix Kling yes, much better. Being nice is for losers, remember this. – Bartek Kosa Jan 22 '15 at 02:52
  • @BartekKosa What are you trying to actually accomplish? maybe's there's a better solution than what you're wanting here – jdphenix Jan 22 '15 at 02:53
  • @BartekKosa It's actually for people who choose to follow the rules here - http://stackoverflow.com/help/be-nice – jdphenix Jan 22 '15 at 02:54
  • @jdphenix I want private variable that can't be accessed from outside and I need it in method which is prototyped. – Bartek Kosa Jan 22 '15 at 02:58
  • @BartekKosa: As we already told, that's simply impossible. jdphenix wanted to know *why* you would need that. What is the goal you're trying to accomplish? – Bergi Jan 22 '15 at 03:19
  • @Bergi it is possible, look here http://www.nczonline.net/blog/2014/01/21/private-instance-members-with-weakmaps-in-javascript/ – Bartek Kosa Jan 22 '15 at 03:23
  • @BartekKosa: Better use symbols then ("private" properties) if you consider ES6 - you should've mentioned that in your question. – Bergi Jan 22 '15 at 03:25
  • @Bergi I don't care if it is ES6 or ES5 when it is working with decent browser. I have a year to accomplish my project and than I will worry about that. – Bartek Kosa Jan 22 '15 at 03:31
  • You assumed that you know better. My question was specific not like your duplicates. And I got mine answered unike your duplicates. – Bartek Kosa Jan 22 '15 at 03:42

1 Answers1

0

var is a function-scoped variable declaration and is therefore inaccessible outside of its function (in this case, the myClass function). Two approaches to your problem would be either making the variable public by using this.privateVariable = 1 or using a closure with access to the variable. Here's a simple example of the latter:

function MyClass(){
  var privateVar = 1;
  this.incrementPrivateVar = function(){
    return privateVar++;
  }
}
var instance = new MyClass();
instance.incrementPrivateVar();

incrementPrivateVar() also returns the value of the private variable, but that can be prevented by simply removing return from that function.


If you're using ES6, there is a new, better way of creating and accessing private data that is essentially bulletproof: WeakMap. This is the example above in ES6:

let privateData = new WeakMap();
class MyClass {
  constructor(data) {
    privateData.set(this, data);
  }
  getData() {
    return privateData.get(this);
  }
}
let instance = new MyClass({
  data1: 1,
  data2: 2
});
instance.getData();

Although you can inspect the contents of privateData in the console, within the script, you need to have the correct, specific instance of MyClass to access the data in privateData. To prevent anyone from having access to what's in privateData, you could simply wrap the let instance = ... in a block, preventing access to the instance variable, and therefore, the contents of privateData.

rioc0719
  • 303
  • 2
  • 11
  • In you answer there is no prototyped method which I was asking about. I want this functionality but with prototyped method. – Bartek Kosa Jan 22 '15 at 02:28
  • @BartekKosa Then I don't believe its possible to access `privateVar` outside of the constructor, because that is the intended behavior of a `var` declaration. – rioc0719 Jan 22 '15 at 02:31
  • If you are sure about that you can post your answer and I will accept it. – Bartek Kosa Jan 22 '15 at 02:33
  • 1
    @BartekKosa According to [this](http://javascript.crockford.com/private.html), my answer is the only viable method to do this in ES5. However, [this](http://www.nczonline.net/blog/2014/01/21/private-instance-members-with-weakmaps-in-javascript/) shows how it can be done in ES6. – rioc0719 Jan 22 '15 at 02:38
  • 1
    this link http://www.nczonline.net/blog/2014/01/21/private-instance-members-with-weakmaps-in-javascript/ answers my question, thank you. – Bartek Kosa Jan 22 '15 at 02:54
  • Post your answer with weakmap example because it is working and it answers my question perfectly. I will accept it. – Bartek Kosa Jan 22 '15 at 03:28