Reputation: 4516
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?
Upvotes: 1
Views: 11217
Reputation: 7080
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 recommend the first way (with Object.defineProperty
) because it is :
Upvotes: 1
Reputation: 2407
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
}
}
Upvotes: 2