1

I've read that using Object.prototype to attach functions to custom JavaScript objects is more efficient than the "traditional" method of this.foo = function(). The problem I've run into is scope. I want these public methods to be able to access private variables of the object. What I ended up doing was this:

function Foo(){
    var id = 5;
    Foo.prototype.bar = function(){
        alert(id);
    };
}
var x = new Foo();
x.bar();

I nested the prototype declaration inside the object definition. This works and seems to solve the problem. Is there any reason to NOT do this? Is there a better or more standard way to accomplish this?

UPDATE Based on some of the responses I've received I guess I need to mention that I'm fully aware that there is no concept of a private variable in JavaScript. I use the term private here meaning not accessible outside the current scope because it's easier to say and write and I assume that anyone trying to answer this question would know what was meant by me using the term private.

1
  • There are some complex tricks that kinda let you access private variables but the standard way is to just use "_" to mark the "private" fields. This is also common in other languages that don't have a public/private distinction, such as Python. Commented Mar 22, 2012 at 19:16

4 Answers 4

1

While your idea works, it may not be working as you expect. I believe your overwrites the prototype each time a new Foo is instantiated. It would potentially change the bar() method for all instances of Foo each time you create a new Foo. Oops.

Here's an example of using fake private variables for someone to "lie" about their real age.

Here is the standard way to do this:

function Person(name, age) {
  this._age = age; // this is private by convention only
  this.name = name; // this is supposed to be public
}

Person.prototype.sayHiTo = function(person) {
  console.log("Hi " + person.name + ", my name is " + this.name);
}

Person.prototype.age = function() {
  return this._age - 3;
}

var j = new Person("Jay", 33);
var k = new Person("Kari", 26);
j.sayHiTo(k) // Hi Kari, my name is Jamund
k.age(); // 23
Sign up to request clarification or add additional context in comments.

5 Comments

That doesn't make _id private though. It is accessible to any instance of Foo.
@Zero21xxx you have the illusion that local variables are private :\ that's a common misconception
I updated my example to add some more silliness. See how you can use fake privates to mask their real age. Obviously, anyone can "see" the real age, but you make internal rules to prevent that. The rule is "don't use _ variables outside of their Protoype"
This is a good example of this pattern. I'm just not a huge fan of the _variable thing to tell someone STAY OUT. Then you have to rely on them not doing anything weird with that value. I guess at this point we're kind of dealing with limitations of the language itself eh?
It keeps things simple, but If you don't care about inheritance or aren't making tons (hundreds) of copies of things, you're probably better off sticking with a simple function that keeps its state held internally.
1

You can use privileged methods to access the private members. More info here: http://javascript.crockford.com/private.html

However, IMO it's really not worth it. It's cumbersome and it cripples classical inheritance. And for what? To "shield" users from accessing your private members directly? It's JS, they have the source and the means to access them anyway, it's really not worth the effort. Underscoring pseudo private members is enough.

Comments

0

There is no private in JavaScript, just do things properly

var Foo = {
    bar: function () {
        console.log(this._id)
    },
    constructor: function () {
        this._id = 5
        return this
    }
}

var x = Object.create(Foo).constructor()
x.bar()

8 Comments

there is no private is not entirely correct as you know. it just follows other patterns
@jAndy there is no private, there are only local variables and closures that access local variables.
"there is no private" is correct. "Other patterns" is correct. Chill out.
@Raynos: ahh, thanks I didn't know that ! However, as I said it's just a different ruleset and other patterns, but you can have true privacy that way nonetheless.
@jAndy There is no such thing as true privacy :\
|
0

here how you can fake it. This is Animal class

(function(window){
        //public variable
        Animal.prototype.speed = 3;

        //public method
        Animal.prototype.run = function(){
            //running
        }

        //private method
        //private method
        function runFaster(){
            //run faster
        }

        //private var
        //private var
        var legCount = 4;    

    }(window));

3 Comments

I think his goal was to let his prototypal functions see variables he passed into his constructor, which AFAIK is impossible.
This doesn't solve his problem though. Obviously we can share private variables between prototypal methods, but how to do this with dynamically. It's not possible.
i am not sure but i believe there is a solution. This is lame JS.

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.