1
\$\begingroup\$

I have very quickly mocked this up as an example model in Angular JS:

.factory('car', function() {
  function car(serial, name, type, manufacturer)
    //intended to be private
    var serial = serial;
    var name = name;
    var type = type;
    var manufacturer = manufacturer;

    this.getSerial = function() {
      return this.serial;
    }

    this.setSerial = function(newSerial) {
      this.serial = newSerial;
    }
});

There would be getters and setters for every property, and there is a legitimate need for getters and setters for all of them.

I am not a hardcore JavaScript developer, but I have been reading that providing getters and setters for every property is bad practice and providing them in general is bad practice.

  1. Let's say there is a legitimate need for getters and setters for all of the properties, is it still bad practice?
  2. Would other developers do it another way? I have also seen developers writing about it doing in completely different ways

I am after encapsulation of these properties and I assume that this is a good way to go about it.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ The convention is to not worry about encapsulation, it's preferable to use prototypes and monkey-patching, than attempting to hide everything. Prefixing "private" variables with an underscore is IMO the way to go. \$\endgroup\$
    – elclanrs
    Jul 3, 2014 at 10:08
  • \$\begingroup\$ Agreed with @elcanrs, except for the underscore. Also, can you expound on your legitimate need \$\endgroup\$
    – konijn
    Jul 3, 2014 at 17:50

1 Answer 1

1
\$\begingroup\$

JavaScript provides a analogy to private properties, but you should think of them as hidden as they do not behave as private properties. Protoptyped methods do not have access to hidden properties.

Properties defined with the "this" token are public and can be accessed anywhere the object can be accessed. Private properties are declared with the var token or as the objects passed parameters and should never require direct getting and setting

function MyObject (id, name) {
    this.id = id;                     // create public property
    var displayVal = "Hi I am "+name; // create Hidden property
    this.display = function () {      // create public function 
         console.log(displayVal);     // this function closes over displayVal
    }
    // closure closes over all currently scoped variables thus
    this.displayName = function () {
         console.log(name)     // the argument passed to this object is also 
                               // available as a hidden property 
    }
}
MyObject.prototype.test = function () { // this prototype does not close over
                                        // the property displayVal
      // the next line will display undefined
      console.log(displayVal);  // undefined
}
var myObj = new MyObject(0, "OBJECT"); // creates a new object
console.log("Public id = " + myObj.id);  // accessing public property
myObj.display();                         // display private property       

// hidden properties are not enumerable        
for(var i in myObj){
    console.log(i + " as " + (typeof myObj[i]) );    // will report
                       // id as number
                       // display as function
                       // displayName as function
                       // test as function
}      
// Note no hidden variables are displayed

JavaScript is a classless language and attempting to transfer class like concepts to it from other languages is bad practice. Use closure to define private (hidden) properties.

Object factories in my view are bad design, they slow down an already slow language and provide no extra benefit to the code.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.