С помощью конструктора ES5 и прототипа я могу добавить общедоступные (прототипы) свойства, как показано ниже:
function Utils(){}
Utils.prototype.data = {};
var utils = new Utils();
console.log(utils.data); //{}
ES6 class
позволяет мне определить только открытые методы в классе. Я создаю приложение с классом-подход, и я не хочу смешивать конструкторы и классы. Рабочий код, который я выяснил, это:
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); //{}
Когда я _data
метод _data
getter, он проверяет, существует ли свойство _data
в объекте прототипа. Если это так, оно возвращает его, иначе оно инициирует свойство _data
.
Это хорошая практика? Есть ли другой способ сделать это лучше?
Я не знаю, является ли код, который вы предоставили, вашим полным кодом или нет, но когда я его запускаю, он выдает ошибку:
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);
Если я правильно вас понимаю, вы хотите, чтобы все экземпляры Utils
использовали одно и то же свойство data
.
Есть несколько способов, которые я могу придумать, чтобы делать то, что вам нужно, но он может "смешивать конструкторы и функции классов" (я не понимаю, что вы подразумеваете под этим).
1: Добрый путь ES5
class Utils {}
Utils.prototype.data = {};
/* TEST */
const a = new Utils();
a.data.ok = 'ok';
const b = new Utils();
console.log(b.data.ok);
2: То же, что и ваш путь, но в нем конструктор
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);
Хотя, поскольку свойство data
необходимо обменивать между экземплярами, я предлагаю вам добавить свойство к его прототипу с использованием метода Object.defineProperty
чтобы сделать его неприемлемым и неудобным:
Object.defineProperty(Utils.prototype, 'data', {
value: {},
writable: false,
enumerable: true,
configurable: false
});
Это необходимо для того, чтобы свойство данных нельзя было переназначить или удалить, что минимизирует вероятность ошибочного сброса данных или т.д.
Я бы порекомендовал первый способ (с Object.defineProperty
), потому что это:
Чтобы сделать data
общедоступными:
class Utils {
constructor () {
this.data = {}
}
}
Чтобы сделать data
общедоступными статическими свойствами, get/set, вероятно, лучший способ:
let data = {}
class Utils {
get _data () {
return data
}
set _data (d) {
data = d
}
}
this
(то естьthis.data = ...
).