2

Consider this trivial code I tried in Chrome's console:

function Container() { var secret = 3; this.getSecret = function() { return secret; } } 

Now, I cannot retrieve 3 by executing:

var c1 = new Container(); c1.secret //yields undefined 

However, this works as expected

c1.getSecret() //returns 3 

Now, this is the quirky thing I tried:

c1.secret = 10; c1.getSecret(); //I was expecting it to return 10 

However, it returns 3. When I see the object in the console, it looks like this:

Container {getSecret: function, secret: 10} 

Can someone explain why c1.secret = 10 didn't change the value of the secret private variable in the object? Are there two fields with the name "secret"?

I'm confused what the final object really looks like in memory.

4
  • 6
    No. .secret is a property of the object, the other is a private variable due to the scope of the function within it's declared. Remember that functions in JS are treated like objects! Commented Jul 19, 2013 at 20:56
  • You might want to google for "javascript closure". The concept needs a little time to get used to. Commented Jul 19, 2013 at 21:01
  • You seem to be confusing the difference between variables and properties (two very different things). A variable (var secret) is accessible in the scope it is declared (in each Container instance). You set a property (getSecret), by using this, which is in the same scope as secret, so you can access it from there. In the scope where you declare c1 (global, I'm guessing), it doesn't have access to the secret variable. Then you dynamically set a "secret" property on a specific instance with c1.secret = 10;, which is shown by the console output. Commented Jul 19, 2013 at 21:01
  • Here's post about private variables & closures, I hope it helps: marcelorjava.wordpress.com/2014/06/07/… Commented Jun 7, 2014 at 11:28

1 Answer 1

4

private is a really confusing word.

The secret var you declared using var secret = 3; is not a 'private' variable. This is a variable that is only visible in the Container constructor scope. And because you declare the method getSecret in the same scope, it has access to it.

if you had done:

function Container() { var secret = 3; } Container.prototype.getSecret = function() { return secret; } 

calling getSecret would say that secret is undefined.

And, with your current code, adding:

Container.prototype.getSecret2 = function() { return this.secret; } 

would return 10. Because your object has now a property called secret when you do

c1.secret = 10;

But remember:

var secret = 3; does not attach the variable to the current object. It just create a variable that live in the current scope. Every function declared in that scope will have access to it.

Sign up to request clarification or add additional context in comments.

3 Comments

I think the most important part is: "var secret = 3; does not attach the variable to the current object."
Thanks for the explanation. Can you also tell me how I could create private variables, or the essence thereof, in object literals?
Thanks for that fiddle, got it. But I must say, it isn't all that straightforward - or maybe I'm just plain dumb :(