views:

597

answers:

4

Found this at MDC but how if I'd wanted to add a private variable to the

var dataset = {
    tables:{
        customers:{
            cols:[ /*here*/ ],
            rows:[ /*here*/ ]
        },
        orders:{
            cols:[ /*here*/ ],
            rows:[ /*here*/ ]
        }
    },
    relations:{
        0:{
            parent:'customers', 
            child:'orders', 
            keyparent:'custid', 
            keychild:'orderid',
            onetomany:true
        }
    }
}

The way I understand OOP in Javascript, I'd have access to dataset.tables.customers.cols[0] if such an item exists.
But if I wanted to place a private variable into customers, what would that look like?
Adding var index = 0; results in a runtime error.

+5  A: 

JavaScript lacks the sort of access controls you get in more rigid languages. You can simulate private access for objects' data using closures, but your example is an object literal - a simple data structure - rather than a constructed object.

It rather depends what you want to do with the object - the normal technique for 'private' members means they are accessible only by member functions, and requires that you use a constructor to create the object. The literal syntax is used for data structures or light weight objects with public data and functions.

The problem with using the private closure pattern is that the fields within a literal are in public scope, but the privacy given by the closure is because the variable is defined in a function, so is scoped locally. You could either create a function which clones the literal and adds private fields, or add a public field which has private data. You also can add closures as members, so create private fields which are method private rather than object private.

dataset = {
    secretCounter: ( 
      function () {
      var c = 0;
      return function () { return ++c; }
    })(),      
   ...

So dataset.secretCounter() has a varable c which is private to that function only.

Pete Kirkham
Oh! I think you got me back on track. Data structures can't hold private members since they just declare the data (everything's public!) but if I rewrite this into a static class/singlelton (var obj = function(){}();), I'll be able to to so. Is that correct? Thank you. :)
Adam Asham
+3  A: 

You can't have "private" variables without a function involved. Functions are the only way to introduce a new scope in javascript.

But never fear, you can add functions in the right place to gain this sort of functionality with your object

var dataset = {
  tables: {
    customers:function(){
      var privateVar = 'foo';
      return { 
        cols:[ /*here*/ ],
        rows:[ /*here*/ ]
      }
    }(),
    orders:{
      cols:[ /*here*/ ],
      rows:[ /*here*/ ]
    }
  },
  relations: [{
    parent:'customers', 
    child:'orders', 
    keyparent:'custid', 
    keychild:'orderid',
    onetomany:true
  }]
};

But this doesn't gain us much. This is still mostly just a bunch of literal objects. These types of "Private" variables have zero meaning since there are no methods - nothing that would actually read or otherwise use the variables in the scope we created by adding a function (a closure).

But if we had a method, that might actually start to become useful.

var dataset = {
  tables: {
    customers:function(){
      var privateVar = 'foo';
      return { 
        cols:[ /*here*/ ],
        rows:[ /*here*/ ],
        getPrivateVar: function()
        {
          return privateVar;
        }
      };
    }(),
    orders:{
      cols:[ /*here*/ ],
      rows:[ /*here*/ ]
    }
  },
  relations: [{
    parent:'customers', 
    child:'orders', 
    keyparent:'custid', 
    keychild:'orderid',
    onetomany:true
  }]
};

alert( dataset.tables.customers.getPrivateVar() );
Peter Bailey
+1  A: 

Private variables in javascript are done using the var keyword inside a closure. Only priviliged methods and attributes can access it. Here's the way to do it:

function dataset()
{
var private_stuff = 10; // private
this.foo = new function() { alert(private_stuff); } // priviliged
return {
    tables:{
        customers:{
                cols:[  ],
                rows:[  ]
        },
        orders:{
                cols:[  ],
                rows:[  ]
        }
    },
    relations:{
        0:{
                parent:'customers', 
                child:'orders', 
                keyparent:'custid', 
                keychild:'orderid',
                onetomany:true
        }
    }
}; // public
}

var d = new dataset;
alert(d.foo());
the_drow
var d = new dataset(); or is it: var d = dataset();
pkario
A: 

This is my attempt to have OOPs JS lib - http://code.google.com/p/oopsjs/

Rajendra