最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to define a public property in the javascript class? - Stack Overflow

programmeradmin4浏览0评论

With ES5 constructor and prototype approach I can add public (prototype) properties as below:

function Utils(){}
Utils.prototype.data = {};

var utils = new Utils();
console.log(utils.data);  //{}

The ES6 class allows me to define only public methods in the class. I build an app with a class-approach and I don't want to mix constructors and classes features. The working code that I figured out is:

class Utils(){
  get _data(){
    const proto = Object.getPrototypeOf(this);
    if(!proto._status) proto._data = {};
    return proto._data;
  }
}

const utils = new Utils();
console.log(utils._data); //{}

When I call _data getter method, it checkes whether the _data property exists in the prototype object. If so, it returns it, otherwise it initiates the _data property.

Is it a good practice? Is there any other way to do it better?

With ES5 constructor and prototype approach I can add public (prototype) properties as below:

function Utils(){}
Utils.prototype.data = {};

var utils = new Utils();
console.log(utils.data);  //{}

The ES6 class allows me to define only public methods in the class. I build an app with a class-approach and I don't want to mix constructors and classes features. The working code that I figured out is:

class Utils(){
  get _data(){
    const proto = Object.getPrototypeOf(this);
    if(!proto._status) proto._data = {};
    return proto._data;
  }
}

const utils = new Utils();
console.log(utils._data); //{}

When I call _data getter method, it checkes whether the _data property exists in the prototype object. If so, it returns it, otherwise it initiates the _data property.

Is it a good practice? Is there any other way to do it better?

Share Improve this question asked Feb 12, 2018 at 0:17 PawełPaweł 4,5366 gold badges25 silver badges42 bronze badges 4
  • Why don't you want to initialize the data property in the ES6 class constructor? Looking at the documentation, it seems like that's the way MDN does it. – Dream_Cap Commented Feb 12, 2018 at 0:27
  • Instance properties are made via this (i.e. this.data = ...). – Scott Marcus Commented Feb 12, 2018 at 0:28
  • This is a way I thought this could work: jsfiddle/r2tc1wd7 . Is this not a good idea @ScottMarcus ? – Dream_Cap Commented Feb 12, 2018 at 0:51
  • 1 @ Dream_Cap if you define data in the constructor, then each instance has its own data property. I want to 'store' it in the prototype so each instance has only the reference to the same data property stored in the class prototype – Paweł Commented Feb 12, 2018 at 1:10
Add a ment  | 

2 Answers 2

Reset to default 2

To make data a public instance property:

class Utils {
  constructor () {
    this.data = {}
  }
}

To make data a public static property, get/set is probably the best way:

let data = {}
class Utils {
  get _data () {
    return data
  }
  set _data (d) {
    data = d
  }
}

I don't know if the code you provided is your full code or not, but when I run it, it throws an error:

class Utils {
  get _data(){
    const proto = Object.getPrototypeOf(this);
    if(!proto._status) proto._data = {};
    return proto._data;
  }
}


/* TEST */
const a = new Utils();
a._data.ok = 'ok';

const b = new Utils();
console.log(b._data.ok);

If I understand you correctly, you want all instances of Utils to share the same data property.

There is a few ways that I can think of to do what you need, but it might "mix constructors and classes features" (I don't really get what you mean by that).

1: Good ol' ES5 way

class Utils {}
Utils.prototype.data = {};

/* TEST */
const a = new Utils();
a.data.ok = 'ok';

const b = new Utils();
console.log(b.data.ok);

2: Same as your way, but in it's constructor

class Utils {
  constructor(){
    if (!this.data) {
      Utils.prototype.data = {};
    }
  }
}

/* TEST */
const a = new Utils();
a.data.ok = 'ok';

const b = new Utils();
console.log(b.data.ok);

Though, as the data property needs to be shared across instances, I'd suggest you to add the property to its prototype using Object.defineProperty method to make it unwritable and unconfigurable:

Object.defineProperty(Utils.prototype, 'data', {
    value: {},
    writable: false,
    enumerable: true,
    configurable: false
});

This is to ensure the data property cannot be reassigned or deleted, thus minimising the chance of mistakenly reset the data or etc.

I'd remend the first way (with Object.defineProperty) because it is :

  1. More foolproof
  2. Clearer
  3. Easier to maintain
发布评论

评论列表(0)

  1. 暂无评论