私有属性/公共getter-javascript

Private property / public getter - javascript

本文关键字:公共 getter-javascript 属性      更新时间:2023-12-06

如何使sku私有,但允许getter访问它:

var Product = function (sku) {
    this.sku = sku;
};
Product.prototype.getSku = function() {
    return this.sku;
}
module.exports = {Product: Product};

由于您同时引用了"private"answers"getter",所以您想要什么并不完全清楚。如果你想要的是外部世界可以获得值,但不能直接设置值,那么有几种方法可以做到这一点:

从Crockfords关于私有成员变量主题的相当古老的文章中,您可以创建一个可以访问私有变量的方法,但没有其他外部访问私有变量(例如,不能从外部设置):

function Product(sku) {
    this.getSku = function() {
        return sku;
    }
}
var p = new Product(1234);
console.log(p.getSku());

变量本身是私有的,不能从外部进行设置。但它的值可以用getSku方法来检索。

其思想是,构造函数函数本地的任何变量(包括参数)只能由构造函数本身和构造函数中定义的任何函数访问,但不能由外部世界访问。

因此,如果在构造函数中对对象定义了一些方法,那么这些方法以及只有这些方法才能访问这些局部变量。因此,它们本质上是私有成员变量,因为它们是私有的并且是按实例的。正是Javascript闭包的概念使它发挥了作用。

这适用于所有浏览器版本。


或者,如果你想让sku像只读属性一样工作,你可以用属性语法而不是方法语法读取它的值,你可以在构造函数中使用Object.defineProperty()只为它定义一个getter,如下所示:

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()需要IE9或更高版本。

使用Object.definePropertiesObject.defineProperty:

var Product = function (sku) {
    Object.defineProperty(this, 'sku', {
        get: function() { return sku }
    })
};
module.exports = {Product: Product};

对于node.js,您也可以使用__defineGetter__(但这种方法在ES规范中已被弃用):

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

在原型上使用Object.defineProperties

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;