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 owndata
property. I want to 'store' it in the prototype so each instance has only the reference to the samedata
property stored in the class prototype – Paweł Commented Feb 12, 2018 at 1:10
2 Answers
Reset to default 2To 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 :
- More foolproof
- Clearer
- Easier to maintain