0

Eric Miraglia of Yahoo/Google presents a very clean looking way to implement information hiding in JavaScript:

http://www.yuiblog.com/blog/2007/06/12/module-pattern/

Please note some experiments here: http://jsfiddle.net/TvsW6/5/

My question is, why can I access the seemingly "public" variable "this.setting2" (and of course not _setting1) YET I cannot access the function "this.logSetting_priv" although it is in the same scope as this.setting2 (isn't it!?!?!?) Does any one know why?

Also, with the use of the return object for the public methods, I can't seem to add a function as I might normally with "LogSystem.prototype.publicFunc1." Why is that?

Mystery of the ages . . .

Pls checkout my JSFiddle but the JS is also below:

function LogSystem() {
    //default
    var _divId = "log";

    var _setting1 = "default stuff";
    this.setting2 = "default stuff as well";; //This is accessible!

    function _printLog(msg) {
        msg = msg || "";
        $("#" + _divId).append(msg + "<br/>");
    };

    //this is **not** accessible - bc of return object below?
    this.logSetting_priv = function () {
        _printLog("PRIV: Setting1 is: " + _setting1);
        _printLog("PRIV: Setting2 is: " + this.setting2);
    };
    /*
     *  Key Distinguishing feature of this pattern
     */
    return {
        printLog: function (msg) {
            console.log("PRINTING:" + msg);
            _printLog(msg);
        },
        logSetting_pub: function () {
            this.printLog("PUB: Setting1 is: " + _setting1);
            this.printLog("PUB: Setting2 is: " + this.setting2);
        },
        publicFunc2: function () {
            _setting1 = "Fixed Deal returnFunction";
            this.setting2 = "floating hamster";
        }
    };

};
//THIS DOESNT WORK!! . . . . bc of the return object??
LogSystem.prototype.publicFunc1 = function () {
    _setting1 = "Fixed Deal";
    this.setting2 = "floating midget";
};


/*******************************/
/*********Testing Code**********/
/*******************************/

$(document).ready(function () {

    var logInst = new LogSystem();
    //TESTING METHODS!
    try {
        logInst.publicFunc1(); //THIS DOESNT WORK!!
    } catch (e) {
        logInst.printLog("The call to the prototype function does not work - WHY?");
        logInst.publicFunc2();
    }

    try {
        logInst.logSetting_pub();
        logInst.logSetting_priv();
    } catch (e) {
        logInst.printLog("ERR!!: " + e.message);
    }

    //TESTING MEMBERS!
    logInst.printLog("We know this does not work? " + logInst._setting1); //undef
    logInst.printLog("Why Does THIS WORK? " + logInst.setting2); //def

});

Thank you!

EDIT: Holy crap - and when I manipulate the prototype of the INSTANCE variable, i seem to break the whole object that was returned: http://jsfiddle.net/TvsW6/7/

If any one understands JS at this level, PLEASE explain that! :)

Thank you all so much. Obviously any one in this conversation is at a level way beyond "I do some jQuery" :)

R Claven
  • 1,160
  • 2
  • 13
  • 27

2 Answers2

1

Your constructor is returning a different object than the one build implicitly with new. Thus, inside the constructor this refers to a different object than the one you actually end up with outside, and that object doesn't have a property called "logSetting_priv".

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • You are so kind! But why then do I have access to "this.setting2"? – R Claven Feb 21 '14 at 20:18
  • Also, so if I did not use the constructor to "return" anything, then I would in that case have gotten the "this" being used in the constructor. So returning something is kind of overriding the normal function of new? – R Claven Feb 21 '14 at 20:21
1

Using private instance variables prevents you from using prototype (functions that need to access them need to be in the constructor body where the privates are declared with var) at the end of this answer is link to a pattern that implements protected. It may take some time to understand how prototpe works and would advice trying to understand the basic workings first before trying to mix it with closures to simulate private/public modifier.

Pointy answered you question correctly that when invoking a function with new but then returning an object would not return the Object referred to as this in the function:

function Test(){
  this.name="some test";
  return {name:"something else"};
}
console.log((new Test()).name);//name:something else

Not returning an object or returning a primitive (string, boolean, number) would cause the this object to be returned:

function Test(){
  this.name="some test";
  return "hello";
}
console.log((new Test()).name);//name:some test
Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160