Niklas B.
Niklas B.

Reputation: 95308

Manipulate variable defined in closure

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?

Upvotes: 6

Views: 1734

Answers (3)

brad
brad

Reputation: 32345

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; }
  }
}

Upvotes: 0

jfriend00
jfriend00

Reputation: 707376

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.

Upvotes: 3

g.d.d.c
g.d.d.c

Reputation: 47988

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.

Upvotes: 2

Related Questions