Private methods called from public methods

Discussion in 'Javascript' started by Robert, May 3, 2006.

  1. Robert

    Robert Guest

    Hi,
    I have been reading the article at
    http://www.crockford.com/javascript/private.html
    and I was wondering if there also was some way to be able to have
    private methods that can be called from public methods, but not from
    outside.
    Just throwing an exception if a private method was called from outside
    would be sufficient, but I don't know how to determine if the method was
    called from outside. Anyone else thought about doing this?

    Robert.
    Robert, May 3, 2006
    #1
    1. Advertising

  2. Robert

    VK Guest

    Robert wrote:
    > I was wondering if there also was some way to be able to have
    > private methods that can be called from public methods, but not from
    > outside.


    A bit strange question. The whole idea of private methods is that they
    *cannot* be called outside. If you can call a method from outside, then
    it is not private. ;-)

    Could you post some code or an object structure you're trying to
    achieve?
    VK, May 3, 2006
    #2
    1. Advertising

  3. Robert

    Robert Guest

    VK wrote:
    > Robert wrote:
    >
    >>I was wondering if there also was some way to be able to have
    >>private methods that can be called from public methods, but not from
    >>outside.

    >
    >
    > A bit strange question. The whole idea of private methods is that they
    > *cannot* be called outside. If you can call a method from outside, then
    > it is not private. ;-)


    Of course I would prefer that the private method could not be called,
    but I would be satisfied with an error.

    > Could you post some code or an object structure you're trying to
    > achieve?
    >


    The code I am thinking of usual public method for black-box
    functionality and private methods for internal support functions.

    For example:

    function List()
    {
    this.array = new Array();
    }
    //public
    List.prototype.insert = insert;
    //private
    List.prototype.shiftRight = shiftRight;

    function insert(obj, index)
    {
    this.shiftRight(index);
    this.array[index] = obj;
    }

    function shiftRight(index)
    {
    // move array elements starting at index one to the right
    }

    The "solution" at http://www.crockford.com/javascript/private.html would
    mean that I have to move everything inside the List constructor.
    Insert must become a privileged method and shiftRight a private method.
    I prefer not having to move everything inside to keep the code more
    legible. If only a method could detect if the call came from in or
    outside then I would be satisfied.

    Robert.
    Robert, May 3, 2006
    #3
  4. Robert

    VK Guest

    Robert wrote:
    > The code I am thinking of usual public method for black-box
    > functionality and private methods for internal support functions.


    This is the way I'm using (please not I'm not a real OOP expert of any
    kind):

    <html>
    <head>
    <title>Untitled Document</title>
    <meta http-equiv="Content-Type"
    content="text/html; charset=iso-8859-1">
    <script>
    function List(arr) {
    this.array = arr || [];
    this.count = List.count;
    }
    List.count = function() {
    if (this instanceof List) {
    return this.array.length;
    }
    else {
    throw new Error('Private method call ourside of scope');
    }
    }

    var obj = new List([1,2,3]);
    try {
    alert( obj.count() );
    alert( List.count() );
    }
    catch(e) {
    alert(e.message);
    }
    </script>
    </head>

    <body>

    </body>
    </html>


    There are other ways different in approaches and needed amount of
    different brackets. I'm using this one as - IMHO - the simpliest one as
    it doesn't require to twist your brains every second by trying to
    figure out what "this" is pointing to in this or that place.

    The drawback of this way is that JScript.Net in quick mode doesn't
    allow Function object augmentation. So if you plan to port some your
    solutions on JScript.Net, you may better use something else. From the
    other side JScript.Net has regular "public" and "private" modifiers, so
    the problem as such is not applicable there.
    VK, May 3, 2006
    #4
  5. Robert

    Robert Guest

    VK wrote:
    > Robert wrote:
    >
    >>The code I am thinking of usual public method for black-box
    >>functionality and private methods for internal support functions.

    >
    >
    > This is the way I'm using (please not I'm not a real OOP expert of any
    > kind):
    >
    > function List(arr) {
    > this.array = arr || [];
    > this.count = List.count;
    > }
    > List.count = function() {
    > if (this instanceof List) {
    > return this.array.length;
    > }
    > else {
    > throw new Error('Private method call ourside of scope');
    > }
    > }


    This checks if it is called AS an instance or static method.
    It does not check if it is called FROM a list instance method.

    In my example this in the shiftRight method would be an instance of
    List, because it is called from the insert method.
    Robert, May 3, 2006
    #5
  6. Robert

    Robert Guest

    Robert wrote:
    > VK wrote:
    >
    >> Robert wrote:
    >>
    >>> The code I am thinking of usual public method for black-box
    >>> functionality and private methods for internal support functions.

    >>
    >>
    >>
    >> This is the way I'm using (please not I'm not a real OOP expert of any
    >> kind):
    >>
    >> function List(arr) {
    >> this.array = arr || [];
    >> this.count = List.count;
    >> }
    >> List.count = function() {
    >> if (this instanceof List) {
    >> return this.array.length;
    >> }
    >> else {
    >> throw new Error('Private method call ourside of scope');
    >> }
    >> }

    >
    >
    > This checks if it is called AS an instance or static method.
    > It does not check if it is called FROM a list instance method.
    >
    > In my example this in the shiftRight method would be an instance of
    > List, because it is called from the insert method.


    And if it's called from outside as list.shiftRight() then this would
    still be and instance of List..

    I forgot to add this.
    Robert, May 3, 2006
    #6
  7. Robert

    VK Guest

    Robert wrote:
    > Robert wrote:
    > > VK wrote:
    > >
    > >> Robert wrote:
    > >>
    > >>> The code I am thinking of usual public method for black-box
    > >>> functionality and private methods for internal support functions.
    > >>
    > >>
    > >>
    > >> This is the way I'm using (please not I'm not a real OOP expert of any
    > >> kind):
    > >>
    > >> function List(arr) {
    > >> this.array = arr || [];
    > >> this.count = List.count;
    > >> }
    > >> List.count = function() {
    > >> if (this instanceof List) {
    > >> return this.array.length;
    > >> }
    > >> else {
    > >> throw new Error('Private method call ourside of scope');
    > >> }
    > >> }

    > >
    > >
    > > This checks if it is called AS an instance or static method.
    > > It does not check if it is called FROM a list instance method.
    > >
    > > In my example this in the shiftRight method would be an instance of
    > > List, because it is called from the insert method.

    >
    > And if it's called from outside as list.shiftRight() then this would
    > still be and instance of List..
    >
    > I forgot to add this.

    Program in C++ and use public/private/protected modifiers as descent
    people do :)
    Seriously: JavaScript doesn't have such modifiers, so it has to be
    severely hacked to get anything close to what you get by a single
    modifier in say Java.

    Here is the most popular (AFAIK) way:
    <http://www.litotes.demon.co.uk/js_info/private_static.html#mProt>

    P.S. I keep promising to myself to eventually understand what and how
    are they doing - but just losing it on the 2nd pair of brackets :-(
    :)
    VK, May 3, 2006
    #7
  8. Robert

    Robert Guest

    VK wrote:
    > Program in C++ and use public/private/protected modifiers as descent
    > people do :)
    > Seriously: JavaScript doesn't have such modifiers, so it has to be
    > severely hacked to get anything close to what you get by a single
    > modifier in say Java.
    >
    > Here is the most popular (AFAIK) way:
    > <http://www.litotes.demon.co.uk/js_info/private_static.html#mProt>
    >


    Thanks. I'll try to read it soon.
    And if all else fails I will just assume that 'private' methods are not
    called by using a convention such as clearly stating they are private
    and using a different syntax for the function names.
    Robert, May 3, 2006
    #8
  9. Robert

    VK Guest

    Robert wrote:
    > And if all else fails I will just assume that 'private' methods are not
    > called by using a convention such as clearly stating they are private
    > and using a different syntax for the function names.


    Here's the voice of a Man Who Got the Life Right! :)
    VK, May 3, 2006
    #9
  10. Robert

    RobG Guest

    Robert wrote:
    > Hi,
    > I have been reading the article at
    > http://www.crockford.com/javascript/private.html
    > and I was wondering if there also was some way to be able to have
    > private methods that can be called from public methods, but not from
    > outside.


    A method that can call a private method is called 'privileged'. From
    memory, the article provides an example of a private & privileged
    functions like:


    var aFn = (function(){
    function privateMethod(x){
    alert('privateMethod called with: ' + x);
    };

    return {
    privilegedMethod : function(x){
    privateMethod(x);
    }
    };
    })();

    aFn.privilegedMethod('blah');


    JavaScript is an object-based language, it isn't fully OO like C++. You
    can't declare a method as private, you can only infer it from the code
    structure as above.


    > Just throwing an exception if a private method was called from outside
    > would be sufficient, but I don't know how to determine if the method was
    > called from outside. Anyone else thought about doing this?


    Make the method so it can't be called from outside and you're done.


    --
    Rob
    RobG, May 3, 2006
    #10
  11. On 03/05/2006 16:24, VK wrote:

    > Robert wrote:
    >
    >> And if all else fails I will just assume that 'private' methods are
    >> not called by using a convention such as clearly stating they are
    >> private and using a different syntax for the function names.


    That's certainly a reasonable approach, as long as the convention is
    clear, simple, and well-documented. However, I really don't see how

    function List() {
    var data = [];

    this.insert = function(value, index) {
    shiftRight(index);
    data[index] = value;
    };


    function shiftRight(i) {
    for (var j = data.length; j > i; j--) {
    data[j] = data[j - 1];
    }
    }
    }

    can be considered illegible (with or without more members).

    > Here's the voice of a Man Who Got the Life Right! :)

    ^^^^^^^^^^^^^^^^^^^^^^^^^^
    You /really/ need to stop making things like that up.

    Stick to well-known English idioms and phrases. If you don't know if one
    qualifies as well-known, don't use it (all English-speaking posters
    should adhere to that, particularly with regard to colloquialisms, not
    just you).

    Mike

    --
    Michael Winter
    Prefix subject with [News] before replying by e-mail.
    Michael Winter, May 4, 2006
    #11
  12. Robert

    Robert Guest

    Michael Winter wrote:
    > On 03/05/2006 16:24, VK wrote:
    >
    >> Robert wrote:
    >>
    >>> And if all else fails I will just assume that 'private' methods are
    >>> not called by using a convention such as clearly stating they are
    >>> private and using a different syntax for the function names.

    >
    >
    > That's certainly a reasonable approach, as long as the convention is
    > clear, simple, and well-documented. However, I really don't see how
    >
    > function List() {
    > var data = [];
    >
    > this.insert = function(value, index) {
    > shiftRight(index);
    > data[index] = value;
    > };
    >
    >
    > function shiftRight(i) {
    > for (var j = data.length; j > i; j--) {
    > data[j] = data[j - 1];
    > }
    > }
    > }
    >
    > can be considered illegible (with or without more members).


    I guess there are two things about this that makes it more illegible for me.
    1) No clear list of (public) methods.
    2) Extra indentation

    I don't know. Maybe I should go for this solution and put a commented
    list of (public) methods outside the constructor.

    What about the memory usage? Isn't it a lot less efficient to have all
    those methods per instance? Or is that negligible?
    Robert, May 4, 2006
    #12
  13. On 04/05/2006 15:43, Robert wrote:

    [snip]

    > I guess there are two things about this that makes it more illegible for
    > me.
    > 1) No clear list of (public) methods.


    That's what documentation is for. :)

    > 2) Extra indentation


    Perhaps one becomes accustomed to that; I certainly can't relate to it.

    [snip]

    > What about the memory usage?


    There is a cost to 'private' data, certainly. During execution of the
    constructor function, function expressions must be reevaluated, and yes,
    the resulting objects will take up more memory than an equivalent
    property of the prototype object (which will only be created once).

    > Isn't it a lot less efficient to have all those methods per instance?
    > Or is that negligible?


    'A lot less efficient'? No. Most of the time, the difference should be
    negligible.

    Mike

    --
    Michael Winter
    Prefix subject with [News] before replying by e-mail.
    Michael Winter, May 4, 2006
    #13
  14. On 03/05/2006 12:26, Robert wrote:

    [snip]

    > //public
    > List.prototype.insert = insert;
    > //private
    > List.prototype.shiftRight = shiftRight;
    >
    > function insert(obj, index)
    > {
    > this.shiftRight(index);
    > this.array[index] = obj;
    > }
    >
    > function shiftRight(index)
    > {
    > // move array elements starting at index one to the right
    > }


    Using function declarations in this way isn't sensible. There is no
    point in creating a variable that won't be used beyond a one-time
    assignment. Use function expressions instead.

    List.prototype.insert = function(obj, index) {
    /* ... */
    };
    List.prototype._shiftRight = function(index) {
    /* ... */
    };

    [snip]

    Mike

    --
    Michael Winter
    Prefix subject with [News] before replying by e-mail.
    Michael Winter, May 4, 2006
    #14
  15. Robert

    VK Guest

    Michael Winter wrote:
    > On 03/05/2006 16:24, VK wrote:
    >
    > > Robert wrote:
    > >
    > >> And if all else fails I will just assume that 'private' methods are
    > >> not called by using a convention such as clearly stating they are
    > >> private and using a different syntax for the function names.

    >
    > That's certainly a reasonable approach, as long as the convention is
    > clear, simple, and well-documented.


    But certainly not the only one possible - I guess I was rather clear on
    it in this thread and I did not try to hide other options.


    > However, I really don't see how
    >
    > function List() {
    > var data = [];
    >
    > this.insert = function(value, index) {
    > shiftRight(index);
    > data[index] = value;
    > };
    >
    >
    > function shiftRight(i) {
    > for (var j = data.length; j > i; j--) {
    > data[j] = data[j - 1];
    > }
    > }
    > }
    >
    > can be considered illegible (with or without more members).



    > > Here's the voice of a Man Who Got the Life Right! :)

    > ^^^^^^^^^^^^^^^^^^^^^^^^^^
    > You /really/ need to stop making things like that up.
    >
    > Stick to well-known English idioms and phrases. If you don't know if one
    > qualifies as well-known, don't use it (all English-speaking posters
    > should adhere to that, particularly with regard to colloquialisms, not
    > just you).


    It is an English idiom though... You may not hear it in London, but
    easy to pick up in West Oakland. :) If you mean to use only British
    idioms used in modern American English then it will be a challenge, as
    very few of them made it though the three centuries. Off my head I know
    only of "What does it have to do with tea and China?" (means "It is
    irrelevant to the current subject"). Amasingly enough it is still well
    known at least in California - despite most of the speakers have no
    clue what tea or China are about in this context.
    VK, May 5, 2006
    #15
  16. VK wrote:
    > Michael Winter wrote:
    >> On 03/05/2006 16:24, VK wrote:

    <snip>
    >>> Here's the voice of a Man Who Got the Life Right! :)

    >> ^^^^^^^^^^^^^^^^^^^^^^^^^^
    >> You /really/ need to stop making things like that up.
    >>
    >> Stick to well-known English idioms and phrases. If you don't
    >> know if one qualifies as well-known, don't use it (all
    >> English-speaking posters should adhere to that, particularly
    >> with regard to colloquialisms, not just you).

    >
    > It is an English idiom though... You may not hear it in
    > London, but easy to pick up in West Oakland. :)


    While it is not uncommon for regional dialects of English to employ
    grammar that is very distinct from normal English grammar the
    questionable wisdom of presenting expressions that employ such grammar
    to an international audience was the point of Michael's comment. No
    matter how common that expression may be in West Oakland its grammar is
    such that it would not qualify as a meaningful statement in English
    throughout most of the English speaking word.

    (Incidentally, I don't believe your assertion that the denizens of West
    Oakland employ English that badly. If you listen you will find that the
    expression that they actually use is distinct from your version.)

    > If you mean to use only British idioms used in modern
    > American English then it will be a challenge,


    As the United States has spend the last 70-odd years exporting talking
    movies and, more recently, television globally, common US English idioms
    are quite familiar to the entire English speaking world. Very few of the
    attempts you make to employ such idioms, expressions or proverbs are
    familiar from exported US popular culture or from the language spoken by
    the many UK resident US citizens that I have know.

    > as
    > very few of them made it though the three centuries.


    > Off my head


    Absolutely.

    > I know only of "What does it have to do with tea and China?"
    > (means "It is irrelevant to the current subject").

    <snip>

    With your talent for being staggeringly irrelevant I can see how you may
    have become familiar with that expression.

    Richard.
    Richard Cornford, May 6, 2006
    #16
  17. Robert

    Lee Guest

    VK said:
    >
    >
    >Michael Winter wrote:
    >> On 03/05/2006 16:24, VK wrote:
    >>
    >> > Robert wrote:
    >> >
    >> >> And if all else fails I will just assume that 'private' methods are
    >> >> not called by using a convention such as clearly stating they are
    >> >> private and using a different syntax for the function names.

    >>
    >> That's certainly a reasonable approach, as long as the convention is
    >> clear, simple, and well-documented.

    >
    >But certainly not the only one possible - I guess I was rather clear on
    >it in this thread and I did not try to hide other options.
    >
    >
    >> However, I really don't see how
    >>
    >> function List() {
    >> var data = [];
    >>
    >> this.insert = function(value, index) {
    >> shiftRight(index);
    >> data[index] = value;
    >> };
    >>
    >>
    >> function shiftRight(i) {
    >> for (var j = data.length; j > i; j--) {
    >> data[j] = data[j - 1];
    >> }
    >> }
    >> }
    >>
    >> can be considered illegible (with or without more members).

    >
    >
    >> > Here's the voice of a Man Who Got the Life Right! :)

    >> ^^^^^^^^^^^^^^^^^^^^^^^^^^
    >> You /really/ need to stop making things like that up.
    >>
    >> Stick to well-known English idioms and phrases. If you don't know if one
    >> qualifies as well-known, don't use it (all English-speaking posters
    >> should adhere to that, particularly with regard to colloquialisms, not
    >> just you).

    >
    >It is an English idiom though... You may not hear it in London, but
    >easy to pick up in West Oakland. :) If you mean to use only British
    >idioms used in modern American English then it will be a challenge, as
    >very few of them made it though the three centuries. Off my head I know
    >only of "What does it have to do with tea and China?" (means "It is
    >irrelevant to the current subject"). Amasingly enough it is still well
    >known at least in California - despite most of the speakers have no
    >clue what tea or China are about in this context.


    It may well be known in that form in California, but more of the
    English-speaking world recognizes it as "What does it have to do
    with the price of tea in China?"


    --
    Lee, May 7, 2006
    #17
    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.

Share This Page