简体   繁体   中英

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};

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 (eg 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);

PS Object.defineProperty() requires IE9 or higher.

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};
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());

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM