views:

758

answers:

3

Well I tried to figure out is this possible in any way. Here is code:

a=function(text)
{
   var b=text;
   if (!arguments.callee.prototype.get)
      arguments.callee.prototype.get=function()
    {
         return b;
    }
    else
      alert('already created!');
}

var c=new a("test");  // creates prototype instance of getter
var d=new a("ojoj");  // alerts already created
alert(c.get())        // alerts test 
alert(d.get())        // alerts test from context of creating prototype function :(

As you see I tried to create prototype getter. For what? Well if you write something like this:

a=function(text)
{
    var b=text;
    this.getText=function(){ return b}
}

... everything should be fine.. but in fact every time I create object - i create getText function that uses memory. I would like to have one prototypical function lying in memory that would do the same... Any ideas?

EDIT:

I tried solution given by Christoph, and it seems that its only known solution for now. It need to remember id information to retrieve value from context, but whole idea is nice for me :) Id is only one thing to remember, everything else can be stored once in memory. In fact you could store a lot of private members this way, and use anytime only one id. Actually this is satisfying me :) (unless someone got better idea). someFunc = function()

{
 var store = new Array();
 var guid=0;
 var someFunc = function(text)
 {
    this.__guid=guid;
    store[guid++]=text;
 }

 someFunc.prototype.getValue=function()
 {
    return store[this.__guid];
 }

 return someFunc;
}()

a=new someFunc("test");
b=new someFunc("test2");

alert(a.getValue());
alert(b.getValue());
+2  A: 

Methods on the prototype cannot access "private" members as they exist in javascript; you need some kind of privileged accessor. Since you are declaring get where it can lexically see b, it will always return what b was upon creation.

geowa4
+2  A: 

JavaScript doesn't provide a mechanism for property hiding ('private members').

As JavaScript is lexically scoped, you can simulate this on a per-object level by using the constructor function as a closure over your 'private members' and defining your methods in the constructor, but this won't work for methods defined in the constructor's prototype property.

Of course, there are ways to work around this, but I wouldn't recommend it:

Foo = (function() {
    var store = {}, guid = 0;

    function Foo() {
        this.__guid = ++guid;
        store[guid] = { bar : 'baz' };
    }

    Foo.prototype.getBar = function() {
        var privates = store[this.__guid];
        return privates.bar;
    };

    Foo.prototype.destroy = function() {
        delete store[this.__guid];
    };

    return Foo;
})();

This will store the 'private' properties in another object seperate from your Foo instance. Make sure to call destroy() after you're done wih the object: otherwise, you've just created a memory leak.

Christoph
Doesn't that mean that I create whole new function object every time I call new Foo () ??
Wilq32
Something doesn't look right here... how does this handle when there are 2 instances of the Foo class?
Jason S
oh, I see... the "store" is shared by the whole class, but the entry in the store is per instance.
Jason S
@Wilq32: no, the function objects will be shared between instances; the outermost function is executed immediatedly (notice the `()` at the end!) - it's just there for namespacing!
Christoph
I look again at it and now I get the concept :)
Wilq32
A: 

this seems like a duplicate of another question

Jason S
That's not true, all solutions there will use memory for creating "getter" function every time you create new object instance. I trying to find solution that does not!
Wilq32
I see. The problem is that you're trying to find functions that are "singletons" (one function per object class) that somehow have access to non-singleton data (different data per object instance). You at least need one function that is a per-instance function.
Jason S
Yep - what I try to achieve to find a hack in this concept :)
Wilq32
@Jason: "You at least need one function that is a per-instance function" - no, he doesn't; a unique id per instance is enough...
Christoph