6

Say I have a Javascript class defined and instantiated like this:

Demo = function() { 
  var abc = "foo";

  return {
    get test() { return abc; }
  }
}

obj = Demo();
obj.test  // evaluates to "foo"

Confronted only with this Demo instance obj, can I change the value of the variable abc belonging to this object, that was defined in the closure introduced by the constructur function?

3 Answers 3

3

var abc is NOT directly available outside the scope of Demo.

If you want to change it from outside that scope, you have to add a method to set it.

Demo = function() { 
  var abc = "foo";

  return {
    get test() { return abc; }
  }

  this.setTest(a) {abc = a;}
}

var obj = new Demo();
obj.setTest("fun");

See this previous discussion for examples of the types of accessors you could use.

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

6 Comments

This is obvious, but I'd prefer not to change the class.
However +1 because I didn't state this explicitely and your suggestion might be helpful for others.
You are using a design pattern that makes abc a "private" variable. See this thread stackoverflow.com/questions/7223667/… for further discussion, but private is private. It is NOT available outside that scope without changing the class.
Yes, this became clear to me now. I just thought there might be some trick like when you want to access private members in Ruby or Python (I have never been involved in serious Javascripting :)
The only trick is to make an accessor method. Private is private until you make an accessor method that exposes it. If you don't want them to be private, you can make the object have public properties that are freely readable or assignable outside the scope of the function. But, you would have to change the class and define abc differently to do that.
|
2

No. This is one of the base uses for a closure - to define private, inaccessible variables. They can be retrieved, but unless there is a "setter" function, they cannot be modified.

1 Comment

Thank you. I will accept jfriend00's answer, simply because it provides a little more help for other users who have the possibility of changing the class interface.
0

I think you're a bit confused here. If you're using Demo like a class, you don't want to invoke it like a function, but rather like an instantiation.

When used with instantiation, you can definitely do this:

function Demo(){
  var abc = "some value";

  this.setAbc = function(val){
    return abc = val;
  }

  this.getAbc = function(){
    return abc;
  }
}

var d = new Demo();
d.getAbc()   // => 'some value';
d.setAbc('another value');
d.getAbc()   // => 'another value';

These types of functions (defined within the 'constructor') are referred to as privileged functions. They have access to both public (ie. defined on the prototype) and private variables. Read this for a good rundown on public/private/privileged members of a 'class'.

note that if you just do:

var d = Demo();

You're not getting an instance of Demo, you're just getting what it returns. In my case undefined.

edit

After reading your post again, the quick answer is just NO, not with your particular definition, you'd have to do something like what I'm doing.

OR if you're sticking with your paradigm:

function Demo(){
  var abc = "some value";

  return {
    get test(){ return abc; },
    set test(val){ abc = val; }
  }
}

2 Comments

Well it returns an object for me and it is how env.js defines the Location class, so probably it's a form of ECMAScript that is understood at least by Rhino and V8 (which is the interpreter I use). In that context, { ... } creates an object and get test() { } defines a property. So the Demo function constructs and returns an object with a property test.
ah sorry, didn't notice the pattern of returning the object. Again, you can't set the variable without modifying your 'class' I updated my answer to reflect that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.