Adam Davies
Adam Davies

Reputation: 2802

JavaScript Objects and public variables

I've trying to create a javascript object with public methods and public variables:

jeeni.DataGrid = (function(elementId){
    var divId = elementId;
    var div;
    var saveUrl;
    var columns;
    var dataUrl;

    var validate = function(){
        console.log("divId: " + (divId));
        console.log("div: " + div);
        console.log("saveUrl: " + saveUrl);
        console.log("columns: " + columns);
        console.log("dataUrl: " + dataUrl);
    };

    return {
        toString:validate,
        dateURL:dataUrl,
        saveURL:saveUrl,
        columnDefs:columns
    };

});

and I use it like this:

<script>
    $(document).ready(function() {

        var grid = new jeeni.DataGrid("myDataGrid");

        grid.saveURL = "http://www.jeeni.co.uk/grid/save";
        grid.dataURL = "http://www.jeeni.co.uk/grid/data";
        grid.columnDefs = "[{text:'Column1',width:75}, {text:'Column2',width:150}]";
        grid.toString();
    });
</script>

But at the console I get:

divId: myDataGrid
div: undefined
saveUrl: undefined
columns: undefined
dataUrl: undefined

Can anyone explain why the undefined variables are undefined. Doesn't the return make them public? And how do I get them to be assignable without having to use getters and setters.

Thanks

Upvotes: 0

Views: 102

Answers (3)

THEtheChad
THEtheChad

Reputation: 2432

You're currently taking the private variables, extracting the VALUES, and returning those in an object. The object you're returning has no REFERENCE to the private variables, it merely has a copy. When you reassign a value after calling your function, you're only changing the copy, not the private variable.

What you need to do is store your data directly on an object as all properties on an object are retrieved via REFERENCE. Example:

jeeni.DataGrid = function(elementId){

    // These are private
    var divId = elementId;
    var div;

    var public = {
      "toString"   : validate,
      "dateURL"    : null,
      "saveURL"    : null,
      "columnDefs" : null
    };

    function validate(){
        console.log("divId: "   + divId);
        console.log("div: "     + div);
        console.log("saveUrl: " + public.saveURL);
        console.log("columns: " + public.columnDefs);
        console.log("dataUrl: " + public.dataURL);
    };

    return public;

};

Upvotes: 1

Zorayr
Zorayr

Reputation: 24922

You need to add () at the end of your function declaration if you want to immediately invoke the function and assign the returned object to jeeni.DataGrid. For example,

var obj = (function (someArg1) {
    return { pubVar1 : someArg1 };
}("Hello World"));

//Alerts "Hello World".
alert(obj.pubVar1); 

To test out the return value of your function/variable, you can always use console.log(obj) and inspect the output on the browser's debug console (if you are using Chrome F12 usually will display this console).

Hope this helps!

Upvotes: 0

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382150

Your pattern builds private fields (it's often the main reason it's used). So when you do

grid.saveURL = ...

you're just adding a new field, not changing the existing hidden one.

If you want public fields, do this :

jeeni.DataGrid = function(elementId){
    this.divId = elementId;
};
jeeni.DataGrid.prototype.validate = function(){
    console.log("divId: " + (this.divId));
    console.log("div: " + this.div);
    console.log("saveUrl: " + this.saveUrl);
    console.log("columns: " + this.columns);
    console.log("dataUrl: " + this.dataUrl);
};

If you want to keep your fields private, then you must add functions to change them but that would be heavier in your case.

Upvotes: 0

Related Questions