[英]convert javascript plain object into model class instance
我需要实现类似 ODM 的小型功能。 我从数据库中获取普通的 javascript 对象,我需要将其转换为我的模型类实例。 让我们假设模型看起来像:
class Model{
constructor(){
this.a = '777';
---- whole bunch of other things ---
}
print(){
console.log(this.a);
}
}
所以我需要将var a = {b:999, c:666}
转换为模型实例并能够在之后调用a.print()
,并且当a.print()
执行时777
应该放在控制台中。 怎么做?
有一个简单的方法。 只需将对象分配给 instance(this)
class Model { constructor(obj){ Object.assign(this, obj) } print(){ console.log(this.a); } } let obj = {a: 'a', b: 'b', c: 'c'} let m = new Model(obj) console.log(m) m.print() // 'a'
如果我正确理解了这个问题,您可以导出一个工厂函数并使用Object.assign
来扩展您的基本Model
:
// Export the factory function for creating Model instances
export default const createModel = function createModel(a) {
const model = new Model();
return Object.assign(model, a);
};
// Define your base class
class Model {
constructor() {
this.a = 777;
}
print() {
console.log(this.a, this.b, this.c)
}
}
并称它为:
const myModel = createModel({ b: 999, c: 666 });
myModel.print();
或者,当然,您可以放弃工厂并将a
作为参数(或其余参数)传递给构造函数,但这取决于您喜欢的编码风格。
我建议重写您的类以将其所有属性存储在单个 JS 对象this.props
中,并在其构造函数中接受此对象:
class Model {
constructor (props = this.initProps()) {
this.props = props
// other stuff
}
initProps () {
return {a: '777'}
}
print () {
console.log(this.props.a)
}
}
然后你就可以将this.props
作为一个普通的 JS 对象存储在你的数据库中,然后使用它轻松地重新创建相应的类实例:
new Model(propsFromDatabase)
但是,如果您不想将所有属性移动到this.props
,您可以使用Object.assign
来保持对象的简单:
class Model {
constructor (props = this.initProps()) {
Object.assign(this, props)
// other stuff
}
initProps () {
return {a: '777'}
}
print () {
console.log(this.a)
}
}
但我建议使用前一种方法,因为它可以保护您免受名称冲突。
这个怎么样?:
var a = Object.create(Model.prototype, {
b: {
enumerable: true, // makes it visible for Object.keys()
writable: true, // makes the property writable
value: 999
}, c: {
value: 666
}
});
你基本上是从它的原型创建一个新的模型实例并将你的新属性分配给它。 您也应该可以调用print
。
如果您需要更一致的类型转换,您还可以创建自己的typecast
函数,如泛型函数
function typecast(Class, obj) {
let t = new Class()
return Object.assign(t,obj)
}
// arbitrary class
class Person {
constructor(name,age) {
this.name = name
this.age = age
}
print() {
console.log(this.name,this.age)
}
}
调用它以将任何对象类型转换为任何类实例,例如
let person = typecast(Person,{name:'Something',age:20})
person.print() // Something 20
就像 G_hi3 的答案一样,但它“自动”创建了属性对象
function Model() { this.a = '777'; } Model.prototype.print = function(){ console.log(this.a); } // Customize this if you don't want the default settings on the properties object. function makePropertiesObj(obj) { return Object.keys(obj).reduce(function(propertiesObj, currentKey){ propertiesObj[currentKey] = {value: obj[currentKey]}; return propertiesObj; }, {}); // The object passed in is the propertiesObj in the callback } var data = {a: '888'}; var modelInstance = Object.create(Model.prototype, makePropertiesObj(data)); // If you have some non trivial initialization, you would need to call the constructor. Model.call(modelInstance); modelInstance.print(); // 888
你可以有一个静态的Model.from
或Model.parse
方法,它返回一个具有这些属性的新模型:
class Model { static defaults = { a: 777, b: 888, c: 999, d: 111, e: 222 }; constructor() { const { defaults } = Model; for (const key in defaults) this[key] = defaults[key]; } print() { console.log(this.a); } static from(data) { const { defaults } = Model; return Object.assign( new Model(), Object.keys(data) .filter((key) => defaults[key]) .reduce((prev, curr) => ({ ...prev, [curr]: data[curr] }), defaults) ); } } const data = { a: "a", b: "b", c: "c", ajkls: "this wont be included" }; const myModel = Model.from(data); console.log("myModel =", myModel); console.log("myModel instanceof Model:", myModel instanceof Model); console.log("myModel.print():") myModel.print();
首先声明一个要在其中转换 JSON 的class
:
class LoginResponse {
constructor(obj) {
Object.assign(this, obj);
}
access_token;
token_type;
expires_in;
}
现在将通用 javascript 对象转换为您想要的类对象:
const obj = {
access_token: 'This is access token1',
token_type: 'Bearer1',
expires_in: 123,
};
let desiredObject = new LoginResponse(obj);
console.log(desiredObject);
输出将是:
LOG {"access_token": "This is access token1", "expires_in": 123, "token_type": "Bearer1"}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.