1

I'm trying to create a class like way of accessing objects with public and private functions/variables, but I'm a little confused as to why this simple test code doesn't work.

// Class type object with just one value.

function Play(arg) { // Constructor.
    var test = arg;

// Private, as not declared with "this." Obviously more complex in the future.
    private_settest = function( val ) {
        test = val;
    }

// Public.
    this.settest = function( val ) {
        private_settest(val);
    }

    this.gettest = function() {
        return test;
    }
}

var a = new Play(1);
var b = new Play(2);
a.settest(100);
console.log(a.gettest());
console.log(b.gettest());

I'd expect the output to be 1 2 but the actual output is 1 100.

I believe this to be a closure issue, anyone care to explain what I'm missing?

When stepping through this.settest(): The closure value of test is 1 (this is correct).

When stepping into private_settest(): The closure value of test is 2. This is wrong, it should be 1.

On stepping out of private_settest() the closure value is back to 1 again. I guess this is the closure being popped.

Help would be appreciated!

Thanks.

trincot
  • 317,000
  • 35
  • 244
  • 286
Steven Haggerty
  • 308
  • 3
  • 15

2 Answers2

1
private_settest = function(val) {
    test = val;
}

This implicitly defines a global variable private_settest, and when you construct new Play(), the global is overwritten each time, referencing the scope of the last initialized instance of Play, in this case b. That is why the "private" function accesses the second instance's scope, as you have observed. This should be changed to

function private_settest(val) {
    test = val;
}

in order to correctly declare a function within each instance's scope.

// Class type object with just one value.

function Play(arg) { // Constructor.
  var test = arg;

  // Private, as not declared with "this." Obviously more complex in the future.
  function private_settest(val) {
    test = val;
  }

  // Public.
  this.settest = function(val) {
    private_settest(val);
  }

  this.gettest = function() {
    return test;
  }
}

var a = new Play(1);
var b = new Play(2);
a.settest(100);
console.log(a.gettest());
console.log(b.gettest());

This produces the expected output 100 2 (not 1 2).

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
1

The problem is that private_settest is a global variable. You did not use var (let, const or function) to declare that function variable with local scope. So every time you call the constructor the previous version of that function is overwritten.

When you then call a.setttest, you actually (via the method) call that single global function that modifies the private variable test which really is the private variable of the b instance (the last one that was created).

If you would have used "use strict", you would have received an error message about this.

trincot
  • 317,000
  • 35
  • 244
  • 286