I was trying to implement some kind of factory that create a class definition in the run time,I figure this work my code look like this
function JsClassFactory() {
this.X = class {
};
this.addMethod = (name, def) => {
let Y = class extends this.X {
constructor() {
super()
this[name] = def
}
}
this.X = Y
return this;
}
this.addAttribute = (name, def) => {
this.addMethod(name, def)
}
this.getClass = function () {
return this.X
};
}
(function () {
const cf = new JsClassFactory()
cf.addAttribute('age', 35)
cf.addAttribute('name', 'chehimi')
cf.addMethod('myName', function () {
console.log(' i am %s', this.name)
})
cf.addMethod('myAge', function () {
console.log('my age is', this.age)
})
let z = new (cf.getClass())
z.myName();
z.myAge()
cf.addAttribute('name', 'ali')
cf.addAttribute('age', 15)
let t = new (cf.getClass())
t.myName();
t.myAge()
})()
i am asking if there is a better a way to implement this feature? or a better work arround,
CodePudding user response:
Here is the approach I would take to accomplish this.
class JSClassBuilder {
constructor(){
this.constructedClass = class { };
this.constructedClassAttributes = { };
}
addStatic(key, value){
this.constructedClass[key] = value;
return this;
}
addAttribute(name, value){
if(typeof definition != 'function'){
this.constructedClassAttributes[name] = value;
return this;
} else throw new TypeError("parameter value must not be of type: 'function'");
}
addMethod(name, definition){
if(typeof definition == 'function'){
this.constructedClass.prototype[name] = definition;
return this;
} else throw new TypeError("parameter definition must be of type: 'function'");
}
constructClass(){
return Object.assign(
new this.constructedClass(),
this.constructedClassAttributes
);
}
}
const classBuilder = new JSClassBuilder();
let c = classBuilder
.addAttribute('age', 35)
.addAttribute('name', 'Chehimi')
.addMethod('myName', function () {
console.log('I am %s', this.name);
})
.addMethod('myAge', function () {
console.log('I am %s', this.age);
})
.constructClass();
c.myName();
c.myAge();
let a = classBuilder
.addAttribute('name', 'Ali')
.addAttribute('age', 15)
.constructClass();
a.myName();
a.myAge();
CodePudding user response:
function JsClassFactory() {
this.X = class {};
this.addMethod = (name, def) => {
if (typeof def !== 'function') throw Error('def must be a function type');
this.addAttribute(name, def);
};
this.addAttribute = function (name, def) {
this.X.prototype[name] =def
return this;
};
this.getClass = function () {
return this.X;
};
}
(function () {
const cf = new JsClassFactory();
cf.addAttribute('age', 35);
cf.addAttribute('name', 'chehimi');
cf.addMethod('myName', function () {
console.log(' i am %s', this.name);
});
cf.addMethod('myAge', function () {
console.log(' i am %s', this.age);
});
let z = new (cf.getClass())();
z.myName();
z.myAge();
cf.addAttribute('name', 'ali');
cf.addAttribute('age', 15);
let t = new (cf.getClass())();
t.myName();
t.myAge();
})();