views:

239

answers:

5

hello, I am trying to apply a method to an existing object which involves using its private variables. The object is setup like so:

function a(given_id)
{
    var id= given_id;
}

now I want to apply some new method to it like so

my_obj = new a('some_id');
my_obj.myMethod = function(){
    alert(id);
}

now if I go my_obj.myMethod() I get an error saying id is undefined. This same code works if I change id from being private to public.

I don't understand why this is happening because if myMethod was defined originally in a as a privileged method it would work. The only thing I can think of is that myMethod is being added as a public method, instead of a privileged one.

Any information on this would be much appreciated.

+2  A: 

use this.id = ... instead of var id = ... (var will give you function scope only aka local variable).

{edit} try:

function Foo(givenId)
{
    var id = givenId;

    this.Bar = function() {
     WScript.Echo(id); //change this to alert(...)
        }
}

var foo = new Foo(52);
foo.Bar();

Again, var in a function has function scope (local variable). If you want to have access to it, declare your privilege function as an inner function to the outer function and use closure to get access to it.

Jimmy Chandra
yes I know that would fix it (as stated above) but I would like to keep the id variable private. var id should be accessible from a privileged method, any ideas how to declare it as privileged while still applying it to an object?
Ori Cohen
see inline edit to the answer.
Jimmy Chandra
yes this works except I am trying to add Bar to Foo. That means I would have to do something like, foo.Bar = function(){....}Using this syntax how would I declare it as privileged?thanks for the reply
Ori Cohen
@Ori: You **can't**. The only way for a method to be privileged is for it to be declared inside the constructor—because the whole concept of private and privileged methods (as described by Crockford) depends on closures to work.
Miles
A: 

I think you have misunderstand the idea of private variables. What you trying to do is access private var as it was protected, but there is no protected variables in JS objects. When you are modifying an object outside its declarations it is treated as an ancestor.

Thinker
If you have a private variable and want to return it you can do it with a privileged method. You can also use such a method to use the variable. This method is denoted by using this.methodName() but I don't know how to do that when applying to method to the instance of the object
Ori Cohen
+3  A: 

I think that you are trying to create a "Privileged Method", basically a method that is able to access the private variables:

function a(given_id) {
     var id= given_id;

     this.myMethod = function()
     {
       alert(id);
     }
}

You cannot declare privileged methos outside the constructor, because if you do so, they wont have access to the constructor's closure.

Recommended reads:

CMS
+1  A: 

You can't do what you want, because there are no private members (per se) in JavaScript. That var inside the constructor function is immediately discarded after the function has returned the new object. Thus there's no way to have later access to it. The only possible way to make it stick somewhere is to catch it in a closure by declaring a member function right there in the constructor (this.foo = function () {}; ). The reason for which you must declare this member function in the constructor is because you need to have nested scopes in order to create a closure. By declaring that function as a member of the prototype object or by assigning it to an already created object, you lose the nested scopes, hence no closure and no access to the so-called private member.

Ionuț G. Stan
A: 

what are an attributes