0

Hi everybody I have read that what I ask is not possible (and I imagine why if considering that private fields are achieved through clousure).

( Eg : previously I have read that post Access "private" variables in prototype )

So I worked to a possible workaround. In my case I would that a private property (called __counter) could be setted only through prototype, because everybody else (except me) who try to access to that "private" field, could potentially break my object's functionality.

function Test(_c) {
    var __counter = _c;

    this.getCounter = function() {
        return __counter;
    };

    this.increment = function() {
        for (var proto in Test.prototype)
            if (Test.prototype[proto] == arguments.callee.caller)
                return ++__counter;

        return undefined;
    };

}

Test.prototype.getNext = function() {
    return this.increment();
};

var t1 = new Test(1);

alert(t1.getCounter());
alert(t1.getNext());
alert(t1.increment());
alert(t1.getCounter());

My question now is if that solution is acceptable, and if it is how to improve some performance issues that I've noticed.

I suppose that looping on object prototype for each call could be expensive (use of hash table instead?) and I know that use of arguments.callee.caller is deprecated (and break the inlining in js compiler).

So excluding that performance issues (that I hope to mitigate), are there practical advantage using that method instead of define all methods in the object constructor? (I know this case is trivial, but for more complex cases where only few properties must be accessed privately and there are a lot of methods that "need" to be defined in the prototype).

3
  • Anything you define in constructor and bing to it's scope (e.g. this.smth = ...) will be created over and over again each time you create a new object with of that type. Commented Dec 27, 2013 at 12:16
  • @birukaze so what is the best (better performance) way to expose getter (or setter) to the rest of the code? I do not know any other technique. Commented Dec 27, 2013 at 14:14
  • I do think that best choice for javascript is using naming convention. Are you really so afraid that some other developer will do the lame thing and brake your code? Is it really your problem, not their? Commented Dec 27, 2013 at 14:21

1 Answer 1

0

No, it's not acceptable, since this code will easily break your "fix":

Test.prototype.myIncrement = function() {
    return this.increment();
};

This is defined in the prototype, and thus it can access this.increment. JavaScript allows prototypes to be modified at runtime, and prototypes edits are shared among all instances of the object.

//Test "class"

var t1 = new Test(1);
Test.prototype.myIncrement = function() {
    return this.increment();
};

console.log(t1.getCounter());
console.log(t1.getNext());
console.log(t1.myIncrement());
console.log(t1.getCounter());

Remember that JavaScript is executed on the client machine, so it can be modified as the owner prefers. You can make it harder to someone to modify your code, but it is never impossible.

Sidenote:

I suppose that looping on object prototype for each call could be expensive (use of hash table instead?) and I know that use of arguments.callee.caller is deprecated (and break the inlining in js compiler).

Yes, it could be extremely expensive, but in this case(since the prototype is small) the true problem is arguments.caller.callee. This is what is causing your performance issues. One last thing, when looping with a for..in operator remember to use hasOwnProperty, or you could have unexpected results.

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

2 Comments

Yes but my goal, was not to make a system that protect my code against an evil client. I would protect my "class" against bad programming practices. In the real case i am writing a "library" that would be a javascript implementation of some C# objects. My main concern now is that i need in some way to expose some internal states of my object to its prototype, but if i do that without any cautions, i risk that a programmer improperly use my object, breaking his functionalities Yes a bad programmer could still change class's code but that is out of my domain of interest.
You are not able to protect client side javascript. Simply so. And you do not need to worry about it. Consistency conflicts should be solved on server side, 'cause you never should trust anything from client side. For everything else feel free to let user to be his\her own enemy.

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.