Один из вариантов - создать класс «Модель» со свойством data
, в котором хранятся все присвоенные ему значения. Используйте API get
/ set
/ unset
для изменения свойств данных. Используйте метод parse
, чтобы получить простое объектное представление модели. Это позволяет создавать вложенные модели.
Если вы создаете приложение, я рекомендую создавать API, а не обращаться к свойствам непосредственно в модели данных. Синтаксис может показаться немного длиннее, но в долгосрочной перспективе, если вам нужно выполнить преобразование данных, будет проще добавить методы в класс. Как и в случае с вашим первоначальным подходом, если вы хотите добавить другие методы в класс, вы рискуете перезаписать их фактическими данными. Лучше иметь свойство data
, в котором хранятся все значения. В противном случае вам не обязательно создавать класс, вы можете просто использовать простой объект, как вы это делаете.
https://jsfiddle.net/cnu6ryab/
Класс
const Model = class {
constructor() {}
get data() {
if(!this._data) this._data = {}
return this._data
}
setDataProperty(key, value) {
if(!this.data[key]) {
Object.defineProperties(this.data, {
['_'.concat(key)]: {
configurable: true,
writable: true,
enumerable: false,
},
[key]: {
configurable: true,
enumerable: true,
get() { return this['_'.concat(key)] },
set(value) { this['_'.concat(key)] = value }
},
})
}
this.data[key] = value
return this
}
unsetDataProperty(key) {
if(this.data[key]) {
delete this.data[key]
}
return this
}
get() {
if(arguments[0]) return this.data[arguments[0]]
return Object.entries(this.data)
.reduce((_data, [key, value]) => {
_data[key] = value
return _data
}, {})
}
set() {
if(arguments.length === 2) {
this.setDataProperty(arguments[0], arguments[1])
} else if(
arguments.length === 1 &&
!Array.isArray(arguments[0]) &&
typeof arguments[0] === 'object'
) {
Object.entries(arguments[0]).forEach(([key, value]) => {
this.setDataProperty(key, value)
})
}
return this
}
unset() {
if(arguments[0]) {
this.unsetDataProperty(arguments[0])
} else {
Object.keys(this.data).forEach((key) => {
this.unsetDataProperty(key)
})
}
return this
}
parse(data = this.data) {
return Object.entries(data).reduce((_data, [key, value]) => {
if(value instanceof Model) {
_data[key] = value.parse()
} else {
_data[key] = value
}
return _data
}, {})
}
}
Использование
let model = new Model()
// Add a property
model.set('a', 1)
console.log(model.get())
/*
{
"a": 1
}
*/
// Add multiple properties
model.set({
'b': 2,
'c': { a: 1, b: 2, }
})
console.log(model.get())
/*
{
"a": 1,
"b": 2,
"c": {
"a": 1,
"b": 2
}
}
*/
// Replace a property
model.set({
a: ['meh', 'heh',]
})
console.log(model.get())
/*
{
"a": [
"meh",
"heh"
],
"b": 2,
"c": {
"a": 1,
"b": 2
}
}
*/
// Remove a single properties
model.unset('a')
console.log(model.get())
/*
{
"b": 2,
"c": {
"a": 1,
"b": 2
}
}
*/
// Remove all properties
model.unset()
console.log(model.get())
/*
{}
*/
// Add another property
model.set('a', 2354234)
// Create a nested model
let nestedModel = new Model()
nestedModel.set('nestedValue', 35234534254)
model.set('nestedModel', nestedModel)
console.log(model.parse())
/*
{
"a": 2354234,
"nestedModel": {
"nestedValue": 35234534254
}
}
*/
// Update the nested model
model.get('nestedModel').set('someNewValue', 'asdfasgaerwkjghak')
console.log(model.parse())
/*
{
"a": 2354234,
"nestedModel": {
"nestedValue": 35234534254,
"someNewValue": "asdfasgaerwkjghak"
}
}
*/