Home > Mobile >  Vanilla js class factory
Vanilla js class factory

Time:12-30

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();
    })();
  • Related