Replacing a private function an keeping access to private variables

Discussion in 'Javascript' started by Gregor Kofler, Jun 27, 2008.

  1. How can I access a private variable when replacing a private function,
    which originally had access to this variable, with another one? Or is it
    just not possible?

    Example:

    function foo() {
    var privateVar = 42;

    var privateFunc = function() {
    alert(privateVar);
    }

    return {
    replacePF: function(f) { privateFunc = f; }
    }
    }

    var obj = foo();
    obj.privateFunc(); // 42

    obj.replacePF(function() { alert("The answer is "+privateVar); }
    obj.privateFunc(); // privateVar is undefined


    Gregor



    --
    http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
    http://web.gregorkofler.com ::: meine JS-Spielwiese
    http://www.image2d.com ::: Bildagentur für den alpinen Raum
    Gregor Kofler, Jun 27, 2008
    #1
    1. Advertising

  2. Re: Replacing a private function an keeping access to privatevariables

    On Jun 26, 8:53 pm, Gregor Kofler <> wrote:
    > How can I access a private variable when replacing a private function,
    > which originally had access to this variable, with another one? Or is it
    > just not possible?
    >
    > Example:
    >
    > function foo() {
    >    var privateVar = 42;
    >
    >    var privateFunc = function() {
    >      alert(privateVar);
    >    }
    >
    >    return {
    >      replacePF: function(f) { privateFunc = f; }
    >    }
    >
    > }
    >
    > var obj = foo();
    > obj.privateFunc(); // 42
    >
    > obj.replacePF(function() { alert("The answer is "+privateVar); }
    > obj.privateFunc(); // privateVar is undefined
    >
    > Gregor
    >
    > --http://photo.gregorkofler.at::: Landschafts- und Reisefotografiehttp://web.gregorkofler.com ::: meine JS-Spielwiesehttp://www.image2d.com     ::: Bildagentur für den alpinen Raum


    I think it's not possible because in the example the obj returned by
    the function foo() doesn't have the function "privateFunc". In fact,
    your first use of privateFunc doesnt work too. The message that i
    have, if i remove the lasts lines is:

    Error: obj.privateFunc is not a function

    And if a add again the lasts lines i receive the error "privateVar is
    undefined" because the last line is missing a parentesis ")", look:

    your: obj.replacePF(function() { alert("The answer is
    "+privateVar); } // privateVar is undefined
    correctef: obj.replacePF( function() { alert("The answer is
    "+privateVar); } );

    The error was like:

    Error: missing ) after argument list
    Line: 28, Column: 27
    Source Code:
    // privateVar is undefined

    The message "privateVar is undefined" were shown because the comments
    after the syntatic error.

    http://programandosemcafeina.blogspot.com
    Tiago Albineli Motta, Jun 27, 2008
    #2
    1. Advertising

  3. Re: Replacing a private function an keeping access to private variables

    Tiago Albineli Motta meinte:

    > I think it's not possible because in the example the obj returned by
    > the function foo() doesn't have the function "privateFunc". In fact,
    > your first use of privateFunc doesnt work too.


    Sigh. I shouldn't post - untested - examples at 2 o' clock in the
    morning... The public method for accessing the private function is of
    course missing (plus the parenthesis). I hope this one's better now:

    function foo() {
    var privateVar = 42;

    var privateFunc = function() {
    alert(privateVar);
    };

    return {
    replacePF: function(f) { privateFunc = f; },
    accessPF: function() { privateFunc(); }
    };
    }

    var obj = foo();
    obj.accessPF(); // 42

    obj.replacePF(function() {
    window.alert("The answer is "+privateVar);
    });
    obj.accessPF(); // privateVar is undefined

    Gregor


    --
    http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
    http://web.gregorkofler.com ::: meine JS-Spielwiese
    http://www.image2d.com ::: Bildagentur für den alpinen Raum
    Gregor Kofler, Jun 27, 2008
    #3
  4. Re: Replacing a private function an keeping access to private variables

    Gregor Kofler wrote:
    > function foo() {
    > var privateVar = 42;
    >
    > var privateFunc = function() {
    > alert(privateVar);
    > };
    >
    > return {
    > replacePF: function(f) { privateFunc = f; },
    > accessPF: function() { privateFunc(); }
    > };
    > }
    >
    > var obj = foo();


    I am curious, why did you choose to use a factory instead of a constructor?

    > obj.accessPF(); // 42
    >
    > obj.replacePF(function() {
    > window.alert("The answer is "+privateVar);
    > });
    > obj.accessPF(); // privateVar is undefined


    It's a closure and `privateVar' in privateFunc() is bound to the execution
    context of foo(), in which `privateFunc' was declared a variable. However,
    the function expression in the obj.replacePF() call creates a closure in
    which `privateVar' is bound to the execution context in which the call is
    executed and the anonymous Function object is created, and in which scope
    chain no object has such a property.

    ISTM the only way to do this is to have a public method that returns
    `privateVar', which would become "protected" through this: Either

    function foo()
    {
    var privateVar = 42;

    var privateFunc = function() {
    window.alert(privateVar);
    };

    return {
    getPrivateVar: function() { return privateVar; },
    replacePF: function(f) { privateFunc = f; },
    accessPF: function() { privateFunc(); }
    };
    }

    var obj = foo();

    or

    function Foo()
    {
    var privateVar = 42;

    var privateFunc = function() {
    window.alert(privateVar);
    };

    this.getPrivateVar = function() { return privateVar; };
    this.replacePF = function(f) { privateFunc = f; };
    this.accessPF = function() { privateFunc(); };
    }

    var obj = new Foo();

    and then

    // 42
    obj.accessPF();

    obj.replacePF(function() {
    window.alert("The answer is " + obj.getPrivateVar());
    });

    // "The answer is 42"
    obj.accessPF();

    (It's the usual simple getter and setter implementation as it is.)


    HTH

    PointedEars
    --
    Use any version of Microsoft Frontpage to create your site.
    (This won't prevent people from viewing your source, but no one
    will want to steal it.)
    -- from <http://www.vortex-webdesign.com/help/hidesource.htm>
    Thomas 'PointedEars' Lahn, Jun 27, 2008
    #4
  5. Re: Replacing a private function an keeping access to private variables

    Thomas 'PointedEars' Lahn meinte:
    > Gregor Kofler wrote:
    >> function foo() {
    >> var privateVar = 42;
    >>
    >> var privateFunc = function() {
    >> alert(privateVar);
    >> };
    >>
    >> return {
    >> replacePF: function(f) { privateFunc = f; },
    >> accessPF: function() { privateFunc(); }
    >> };
    >> }
    >>
    >> var obj = foo();

    >
    > I am curious, why did you choose to use a factory instead of a constructor?


    I've started switching from constructor instantiation to a factory like
    pattern after reading Crockfords new book, and realizing that I tend to
    have objects with a meager amount of public properties, but lots of
    private functions. On the other hand I do need a factory occassionally.
    Since I try to avoid mixing the patterns, I stick to factories most of
    the time now.

    >> obj.accessPF(); // 42
    >>
    >> obj.replacePF(function() {
    >> window.alert("The answer is "+privateVar);
    >> });
    >> obj.accessPF(); // privateVar is undefined

    >
    > It's a closure and `privateVar' in privateFunc() is bound to the execution
    > context of foo(), in which `privateFunc' was declared a variable. However,
    > the function expression in the obj.replacePF() call creates a closure in
    > which `privateVar' is bound to the execution context in which the call is
    > executed and the anonymous Function object is created, and in which scope
    > chain no object has such a property.


    Yep, I know the reason, why I can't access it this way, but I was rather
    tired yesterday evening and had this feeling that missed something.

    > ISTM the only way to do this is to have a public method that returns
    > `privateVar', which would become "protected" through this


    [snip]

    Ok, that's the approach I already use.

    > HTH


    Sort of.

    Gregor


    --
    http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
    http://web.gregorkofler.com ::: meine JS-Spielwiese
    http://www.image2d.com ::: Bildagentur für den alpinen Raum
    Gregor Kofler, Jun 27, 2008
    #5
  6. Gregor Kofler

    Guest

    Re: Replacing a private function an keeping access to privatevariables

    On Jun 26, 4:53 pm, Gregor Kofler <> wrote:
    > How can I access a private variable when replacing a private function,
    > which originally had access to this variable, with another one? Or is it
    > just not possible?


    If possible for your scenario, you could potentially use eval for
    this. For example:


    function MyClass(val)
    {
    var printIt = function () { window.alert("1:" + val); }
    this.callPrintIt = function () { printIt(); }
    this.setPrintIt = function (evalStr) { eval("printIt = " +
    evalStr); }
    }

    var c = new MyClass("test");
    c.callPrintIt();
    c.setPrintIt("function () { window.alert(\"2:\" + val); }");
    c.callPrintIt();


    Thanks
    , Jun 27, 2008
    #6
  7. Re: Replacing a private function an keeping access to private variables

    meinte:
    > On Jun 26, 4:53 pm, Gregor Kofler <> wrote:
    >> How can I access a private variable when replacing a private function,
    >> which originally had access to this variable, with another one? Or is it
    >> just not possible?

    >
    > If possible for your scenario, you could potentially use eval for
    > this.


    No I never thought of eval() - for a lot of reasons. Anyway, it might
    work in this example, but not in my real life problem, where a mousemove
    listener is replaced by a custom function, which should still be able to
    access the "hidden" variables of the object.

    Gregor



    --
    http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
    http://web.gregorkofler.com ::: meine JS-Spielwiese
    http://www.image2d.com ::: Bildagentur für den alpinen Raum
    Gregor Kofler, Jun 27, 2008
    #7
    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. Jeremy Bowers
    Replies:
    3
    Views:
    513
    Steven Bethard
    Jan 24, 2005
  2. Replies:
    9
    Views:
    942
  3. Rob Meade

    Replacing - and not Replacing...

    Rob Meade, Apr 5, 2005, in forum: ASP General
    Replies:
    5
    Views:
    274
    Chris Hohmann
    Apr 11, 2005
  4. Rob Long
    Replies:
    2
    Views:
    107
    Rob Long
    May 27, 2006
  5. jacob navia
    Replies:
    1
    Views:
    381
    gwowen
    Apr 3, 2012
Loading...

Share This Page