Private instance members

Discussion in 'Javascript' started by Will, Oct 24, 2003.

  1. Will

    Will Guest

    Is it possible to have private instance members in a javascript class?

    function myObject() {
    var private = 1;

    this.getPrivate = function() {
    return private;
    }

    this.incrementPrivate = function() {
    private += 1;
    }
    }

    var a = new myObject();
    var b = new myObject();
    a.incrementPrivate();

    When I test the example above, calling b.getPrivate() returns 2, so it
    appears that private members can only be static? I know that it is
    possible to use "this.private" to achieve the intended functionality
    with a public member but would prefer to make the variable "private"
    inaccessible to code outside the class.
    Will, Oct 24, 2003
    #1
    1. Advertising

  2. Will wrote:

    > Is it possible to have private instance members in a javascript class?
    >
    > function myObject() {
    > var private = 1;
    >
    > this.getPrivate = function() {
    > return private;
    > }
    >
    > this.incrementPrivate = function() {
    > private += 1;
    > }
    > }
    >
    > var a = new myObject();
    > var b = new myObject();
    > a.incrementPrivate();
    >
    > When I test the example above, calling b.getPrivate() returns 2, so it
    > appears that private members can only be static? I know that it is
    > possible to use "this.private" to achieve the intended functionality
    > with a public member but would prefer to make the variable "private"
    > inaccessible to code outside the class.


    Which browser are you using?
    private is a reserved word I think therefore Netscape gives an error and
    shouldn't yield a result at all.
    And if I try

    function myObject() {
    var private = 1;

    this.getPrivate = function() {
    return private;
    }

    this.incrementPrivate = function() {
    private += 1;
    }
    }

    var a = new myObject();
    var b = new myObject();
    a.incrementPrivate();
    alert(b.getPrivate())

    with IE6 it alerts 1.
    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Oct 24, 2003
    #2
    1. Advertising

  3. > function myObject() {
    > var private = 1;
    >
    > this.getPrivate = function() {
    > return private;
    > }
    >
    > this.incrementPrivate = function() {
    > private += 1;
    > }
    > }
    >
    > var a = new myObject();
    > var b = new myObject();
    > a.incrementPrivate();
    >
    > When I test the example above, calling b.getPrivate() returns 2, so it
    > appears that private members can only be static? I know that it is
    > possible to use "this.private" to achieve the intended functionality
    > with a public member but would prefer to make the variable "private"
    > inaccessible to code outside the class.


    I ran it through JSLINT and it found that you are misusing 'private', a
    reserved word.

    http://www.crockford.com/javascript/lint.html
    Douglas Crockford, Oct 24, 2003
    #3
  4. Will

    Will Guest

    Sorry for the confusion. The previous example was thrown together for
    demonstration purposes and I should have remembered about "private"
    being a reserved word.

    The problem actually relates to private instance variables with a
    prototyped class. For example:

    function myObject() {
    var i = 1;
    this.ret = function() {return i;}
    this.increment = function() {i += 1;}
    }

    myObject2.prototype = new myObject();
    function myObject2() {}

    var a = new myObject2();
    var b = new myObject2();
    a.increment();
    alert(b.ret())

    In this example,b.ret() returns 2 where I would expect 1. It appears
    as though both objects "a" and "b" share an instance of the prototyped
    class "myObject()", because the methods of each object alter the value
    of the private variable for both.

    I find this behaviour a bit odd and wonder if there is either
    something I am missing or a workaround to enable the two objects to
    maintain the variable "i" independently of one another whilst keeping
    "i" as a private variable.
    Will, Oct 25, 2003
    #4
  5. Will wrote:

    > Sorry for the confusion. The previous example was thrown together for
    > demonstration purposes and I should have remembered about "private"
    > being a reserved word.
    >
    > The problem actually relates to private instance variables with a
    > prototyped class. For example:
    >
    > function myObject() {
    > var i = 1;
    > this.ret = function() {return i;}
    > this.increment = function() {i += 1;}
    > }
    >
    > myObject2.prototype = new myObject();
    > function myObject2() {}
    >
    > var a = new myObject2();
    > var b = new myObject2();
    > a.increment();
    > alert(b.ret())
    >
    > In this example,b.ret() returns 2 where I would expect 1. It appears
    > as though both objects "a" and "b" share an instance of the prototyped
    > class "myObject()", because the methods of each object alter the value
    > of the private variable for both.
    >
    > I find this behaviour a bit odd and wonder if there is either
    > something I am missing or a workaround to enable the two objects to
    > maintain the variable "i" independently of one another whilst keeping
    > "i" as a private variable.


    The beahviour is not odd, and your explanation is quite right, the two
    objects share an "instance of myObject" as their prototype, that is how
    prototyping works, an object is created and serves as the prototype.
    Whoever has sold this approach of "private instance members" should have
    told you that it breaks with prototypes being introduced.
    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Oct 25, 2003
    #5
  6. Will

    Will Guest

    Will, Oct 25, 2003
    #6
  7. "Martin Honnen" <> wrote in message
    news:3f9a4015$...
    <snip>
    >Whoever has sold this approach of "private instance members"
    >should have told you that it breaks with prototypes being
    >introduced.


    As Douglas Crockford appears to be responsible for inventing the
    technique for emulating private instance members in JavaScript (though I
    can't see that as "selling") it is probably not surprising that he has
    also published pages on alternative approaches to inheritance, some of
    which would address this problem.

    As the emulation of private instance members is achieved by forming a
    closure, in which the private members are stored, by assigning inner
    functions of the constructor to public members of the object instance,
    the technique results in each object instance being associated with a
    closure. Assigning an super class object instance to the prototype
    results in only one closure being associated with all instances of the
    subclass, but the subclass instances do not each have a closure of their
    own to hold any private instance members that they may want. Attaching a
    closure to the prototype is an action that can be exploited as one of
    the methods of emulating private static members (the other (and perhaps
    preferable) method being to associate a closure with the class
    constructor).

    For instances of a class to inherit private instance member
    functionality from a superclass they would have to explicitly create the
    same closure as the superclass, which could be achieved by using the
    Function.prototype.apply or call methods to apply the superclass
    constructor to the - this - object (probably within the subclass
    constructor).

    Richard.
    Richard Cornford, Oct 28, 2003
    #7
  8. Richard Cornford wrote:
    > For instances of a class to inherit private instance member
    > functionality from a superclass they would have to explicitly create the
    > same closure as the superclass, which could be achieved by using the
    > Function.prototype.apply or call methods to apply the superclass
    > constructor to the - this - object (probably within the subclass
    > constructor).


    Sure, but apply/call only made it into IE5.5/JScript 5.5 and are not
    supported in earlier JScript versions so in my view can't be relied on
    currently on Web pages.

    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Oct 28, 2003
    #8
  9. "Martin Honnen" <> wrote in message
    news:3f9e801f$...
    <snip>
    >>... , which could be achieved by using the
    >>Function.prototype.apply or call methods to apply the
    >>superclass constructor to the - this - object (probably
    >>within the subclass constructor).

    >
    >Sure, but apply/call only made it into IE5.5/JScript 5.5 and
    >are not supported in earlier JScript versions so in my view
    >can't be relied on currently on Web pages.


    True, they are missing from IE 4 & 5.0, but they can each be emulated
    when absent, and that addresses web page reliability issues (obviously
    at the cost of maybe 20 extra lines of code).

    On the other hand I have not seen much need for inheritance in a web
    page environment, they are just not that complicated. Where I do see
    inheritance being a significant consideration is with the implementation
    of business logic in an ASP/IIS environment. But then the JScript
    version is known so reliability is not an issue.

    Richard.
    Richard Cornford, Oct 28, 2003
    #9
  10. Will wrote:
    > Is it possible to have private instance members in a javascript class?


    No, and unless you are talking about JavaScript 2.0 there are no classes
    in JavaScript. The below declares and defines a constructor function
    for a prototype object and therefore that object itself.

    > function myObject() {
    > var private = 1;
    >
    > this.getPrivate = function() {
    > return private;
    > }
    >
    > this.incrementPrivate = function() {
    > private += 1;
    > }
    > }
    >
    > var a = new myObject();
    > var b = new myObject();
    > a.incrementPrivate();


    The `new' operator creates a new object based on the prototype
    object (inheriting its properties) and returns a reference to
    that object which you assign to variables here, making their
    identifiers object references on which the lookup operator `.'
    can be applied.

    Since in prototype-based languages like JavaScript 1.x every
    object is an `instance', it is better to avoid that term there
    to avoid confusion.

    See
    http://devedge.netscape.com/library/manuals/2000/javascript/1.5/guide/obj2.html#1008342


    PointedEars
    Thomas 'PointedEars' Lahn, Nov 23, 2003
    #10
  11. > > Is it possible to have private instance members in a javascript class?
    >
    > No, and unless you are talking about JavaScript 2.0 there are no classes
    > in JavaScript. The below declares and defines a constructor function
    > for a prototype object and therefore that object itself.


    Yes, actually. The problem with the example below is that it misuses 'private',
    a reserved word unfortunately. If you replaced it with a non-reserved word, then
    it would act as a private instance variable that can only be access through the
    priviledged functions.

    > > function myObject() {
    > > var private = 1;
    > >
    > > this.getPrivate = function() {
    > > return private;
    > > }
    > >
    > > this.incrementPrivate = function() {
    > > private += 1;
    > > }
    > > }
    > >
    > > var a = new myObject();
    > > var b = new myObject();
    > > a.incrementPrivate();


    See http://www.crockford.com/javascript/private.html
    Douglas Crockford, Nov 23, 2003
    #11
  12. Will wrote:

    > Please to report that I have now found the answer, thanks to this
    > excellent article:


    You are wrong.

    > http://www.pbwizard.com/Articles/class_inheritance.htm
    >
    > Well worth a read.


    The information provided in this document is awfully wrong, most
    certainly based on a lack of knowledge about prototype-based languages
    in general and especially JavaScript 1.x. As for example:

    > [...]
    > Data Members
    >
    > Note: Data members are variables (including object references) and
    > functions.
    >
    > Within an object there are two types of data members supported by
    > JavaScript. Public and private. Public data members are those
    > properties that we assign to the this object within the constructor.


    There is no distinction between private and public properties in
    JavaScript 1.x and where a property is defined does not change its
    access restrictions because there are simply *none*.

    function Foo()
    {
    this.x = 42;
    this.blurb = function() { return false; };
    }

    var b = new Foo();
    b.y = 23;
    b.haha = function() { return true; };
    Foo.x = -1;
    alert(x);
    alert(y);
    alert(Foo.x);
    alert(Foo.blurb());
    alert(b.blurb());
    alert(b.haha());


    PointedEars
    Thomas 'PointedEars' Lahn, Nov 23, 2003
    #12
  13. Douglas Crockford wrote:
    > [...] The problem with the example below is that it misuses 'private',
    > a reserved word unfortunately. If you replaced it with a non-reserved word, then
    > it would act as a private instance variable that can only be access through the


    s/as/like/

    > priviledged functions.


    ACK. Although understandable, I find that
    way of coding somehow strange, though.

    >> > function myObject() {
    >> > var private = 1;
    >> > [...]


    PointedEars
    Thomas 'PointedEars' Lahn, Nov 23, 2003
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JFCM
    Replies:
    4
    Views:
    5,714
  2. CoolPint
    Replies:
    8
    Views:
    948
    Jeff Schwab
    Dec 14, 2003
  3. Dave
    Replies:
    3
    Views:
    354
    tom_usenet
    Aug 10, 2004
  4. hdixon
    Replies:
    3
    Views:
    617
    hdixon
    Jul 9, 2006
  5. lovecreatesbeauty
    Replies:
    43
    Views:
    1,275
    Keith Thompson
    Feb 6, 2006
Loading...

Share This Page