2

I was wondering how I could make private variables in javascript through clojure. But still have them cloned when using Object.create.

var point = {};
(function(){
  var x, y;
  x = 0;
  y = 0;
Object.defineProperties(point, {
    "x": {
      set: function (value) {
        x = value;
      },
      get: function() {
        return x;
      }
    },
    "y": {
      set: function (value) {
        y = value;
      },
      get: function () {
        return y;
      }
    }
  });
}());

var p1 = Object.create(point);
p1.x = 100;
console.log(p1.x); // = 100
var p2 = Object.create(point);
p2.x = 200;
console.log(p2.x); //= 200
console.log(p1.x); //= 200

I got this technique from http://ejohn.org/blog/ecmascript-5-objects-and-properties/ but it got this limitation that the closure variables is the same on all Objects. I know this behaviour on javascript is supposed but how can I create true private variables?

3
  • this code looks auto generated, was it generated by clojure code? Commented Apr 8, 2012 at 22:38
  • Nope it wasn't why do you think it looks auto-generated? Commented Apr 8, 2012 at 22:45
  • As an alternative without private variables could be jsfiddle.net/heera/G9E9m Commented Apr 8, 2012 at 23:34

2 Answers 2

3

I know this behaviour on javascript is supposed but how can I create true private variables?

You can't, there is no private in ES5. You can use ES6 private names if you want.

You can emulate ES6 private names with ES6 WeakMaps which can be shimmed in ES5. This is an expensive and ugly emulation, that's not worth the cost.

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

1 Comment

I think, as an alternative without private variables could be jsfiddle.net/heera/G9E9m
0

When you need to add private variables to just one object which was created with Object.create you can make this:

var parent = { x: 0 }
var son = Object.create(parent)
son.init_private = function()
{
    var private = 0;
    this.print_and_increment_private = function()       
    {
        print(private++);
    } 
}
son.init_private()
// now we can reach parent.x, son.x, son.print_and_increment_private but not son.private

If you want you can even avoid unnecessary public function init_private like this:

(function()                                                                                                                                                                                                    
{                                                                                                                                                                                                              
    var private = 0;
    this.print_and_increment = function()
    {
        print(private++);
    }
}
).call(son)

Bad thing is that you could not append private members with several calls. The good thing is that this method is quite intuitive in my opinion.

This code was tested with Rhino 1.7 release 3 2013 01 27

Comments

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.