Marty Wallace
Marty Wallace

Reputation: 35734

Private property / public getter - javascript

How do i make sku private but allow the getter access to it:

var Product = function (sku) {
    this.sku = sku;
};

Product.prototype.getSku = function() {
    return this.sku;
}

module.exports = {Product: Product};

Upvotes: 2

Views: 674

Answers (4)

jfriend00
jfriend00

Reputation: 707436

Since you refer to both "private" and "getter", it's not entirely clear what you want. If what you want is that the outside world can obtain the value, but cannot set the value directly, then there are a couple ways to do that:

Taking from Crockfords fairly old article on the topic of private member variables, you can create a method that has access to the private variable, but there is no other external access to the private variable (e.g. it cannot be set from the outside):

function Product(sku) {
    this.getSku = function() {
        return sku;
    }
}

var p = new Product(1234);
console.log(p.getSku());

The variable itself is private and cannot be set from the outside. But it's value can be retrieved with the getSku method.

The idea is that any variables that are local to the constructor function (including the arguments) are accessible only to the constructor itself and to any functions defined in the constructor, but not accessible to the outside world.

So, if you define some methods on the object in the constructor, then those methods and only those methods can access those local variables. As such, they are essentially private member variables because they are private and per-instance. It is the concept of Javascript closures that make this work.

This works with all browser versions.


Or, if you want sku to work like a read-only property where you can read it's value with property syntax rather than method syntax, you can define only a getter for it using Object.defineProperty() in the constructor like this:

function Product(sku) {
    Object.defineProperty(this, "sku", {
        get: function() { return sku;},
        writable: false,       // default value, doesn't have to be specified
        configurable: false,   // default value, doesn't have to be specified
        enumerable: false
    });
}

var p = new Product(1234);
console.log(p.sku);

P.S. Object.defineProperty() requires IE9 or higher.

Upvotes: 5

oaleynik
oaleynik

Reputation: 675

Use Object.defineProperties on prototype:

var Product = function (sku) {
  this._sku = sku;
};

Object.defineProperties(Product.prototype, {
  "sku": {
    get: function () { return this._sku; },
    set: function () { throw new Error("cannot set sku"); }
  }
});

module.exports = Product;

Upvotes: 0

alexpods
alexpods

Reputation: 48505

Use Object.defineProperties or Object.defineProperty:

var Product = function (sku) {

    Object.defineProperty(this, 'sku', {
        get: function() { return sku }
    })
};

module.exports = {Product: Product};

For node.js you also can use __defineGetter__ (but this method was deprecated in ES spec):

var Product = function (sku) {

    this.__defineGetter__('sku', function() {
        return sku;
    });
};

module.exports = {Product: Product};

Upvotes: 2

gongzhitaao
gongzhitaao

Reputation: 6682

var Foo = (function(){

  var a_ = 0;

  function ret(v) {
    if (v) a_ = v;
    return ret;
  }

  // getter and setter for a_
  ret.a = function(v) {
    if (v) a_ = v;
    return a_;
  };

  return ret;

})();

var foo = Foo();
console.log(foo.a());
foo.a(33);
console.log(foo.a());

var bar = Foo(100);
console.log(bar.a());

Upvotes: 0

Related Questions