1

I was reading Crockford's tutorial http://javascript.crockford.com/private.html. private variables are implemented by function inside constructor that makes possible to associate private variables to closure.

Generally javascript libraries are open, so anyone can see and modify the private variables by modifying the inner function of constructor thru instances/objects. like this: c1.radius = function (){return 500;};

Be more precisly: In real OOPS no one can modify private variable by objects but here we can.

Can anyone please suggest me the way to make it full tamper proof like JAVA or C?

function Circle(radius) {

this.radius = function(){ return radius;}

}

Circle.prototype = {
   constructor: Circle,
   area: function(){
       return (Math.PI)* (Math.pow(this.radius(),2));
   }
};

c1 = new Circle(5);
console.log(c1.radius());
console.log(c1.area());
c1.radius = function (){return 500;};
P K
  • 9,972
  • 12
  • 53
  • 99
  • 4
    Anyone can modify any object that they have access to. – zzzzBov Nov 30 '11 at 17:49
  • 1
    Anything needing to be _that_ private should perhaps be stored on the server instead (and even then you can intercept the AJAX call). – Brad Christie Nov 30 '11 at 17:49
  • i am not biased towards java or c, just asking – P K Nov 30 '11 at 17:56
  • 1
    *tamper proof like JAVA...*: See http://stackoverflow.com/questions/1555658/is-it-possible-in-java-to-access-private-fields-via-reflection Nothing is *Tamper Proof*. If something breaks because someone has found a way to circumvent the design (we are talking about *encapsulation*, and not *security*, as in *data security* here), then its their mistake, not the design's. (btw, can there be *private variables* in C?) – Nivas Nov 30 '11 at 17:59
  • What is wrong with Crockford's description of how to make private variables in the article you reference? They are private. Only your methdos defined in the constructor can modify them. Outside code cannot modify them. Even your own code defined elsewhere cannot modify them. – jfriend00 Nov 30 '11 at 18:03
  • objects can not modify private variables in real OOPS. In javascript we can modify private variables using objects. – P K Nov 30 '11 at 18:04
  • i can modify outside the constructor code, please read again... – P K Nov 30 '11 at 18:05
  • @Praveen - In Crockford's private example, the variable `secret` cannot be modified by any code that is not defined inside the contructor. That variable is private and available only to the code defined in that scope. Try modifying it from anywhere else. You can't. – jfriend00 Nov 30 '11 at 18:37
  • i know secret is a variable that doesn't need to set anywhere, but something that need to be set in constructor can be modified further by any of the object. – P K Nov 30 '11 at 18:40

3 Answers3

2

What about this?

function oTest(){
  var a; // "private"
  this.b; // "public"

  this.get_a = function(){
    return a
  )
}

var aTest = new oTest();
aTest.private_get = function(){
  return a
} 

aTest.private_get() // ReferenceError: a is not defined
aTest.get_a() // works

I'm not sure I fully understand your question, but a is only available to the original set of methods provided.

tkone
  • 22,092
  • 5
  • 54
  • 78
2

1st off, don't worry too much about making it tamper proof. If somebody really wants to, they'll be able to access what they want.

2ndly, you can't really do this unless you're using ECMAScript 5 (IE9+, Safari 5+, Chrome 7+, FF 4+). If you're using an ES5 browser, you can do what you want using the Object.defineProperty method, or using Object.create:

function Circle(radius) {
    Object.defineProperty(this, 'radius', {
        value: radius
    });
}

NOTE: When using Object.create or Object.defineProperty, properties are by default non-writable, non-configurable (type can't be changed and property can't be deleted), and non-enumerable (won't show up in for(var x in obj) constructs).

rossipedia
  • 56,800
  • 10
  • 90
  • 93
1

You might want to look at traits.js. In the following example radius and area are immutable or tamper proof.

function TCircle(radius) {
    return Trait.create(
        Object.prototype,
        Trait({
            radius: radius,
            area: function() {
                return (Math.PI) * (Math.pow(this.radius, 2));
            }
        }));
}

var circle = TCircle(5);
console.log(circle.area()); // 78.53981633974483
circle.radius = null;
console.log(circle.area()); // 78.53981633974483
circle.radius = 99;
console.log(circle.area()); // 78.53981633974483

If you want a mutable object then you would use Object.create rather than Trait.create above.

kreek
  • 8,774
  • 8
  • 44
  • 69