【问题标题】:Vanilla js class factory香草js类工厂
【发布时间】:2021-12-29 22:40:44
【问题描述】:

我试图实现某种在运行时创建类定义的工厂,我认为这项工作我的代码看起来像这样


 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) => {
        return 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()
})()

我在问是否有更好的方法来实现此功能? 或者更好的工作环境,

【问题讨论】:

  • “更好的解决方法”在性能或编码风格/实现方面?我认为你在性能方面很好,尽管 addMethod 方法可以只返回一个引用第二个参数方法的实际(非箭头)函数,并且它不会让许多经验丰富的 JS 开发人员感到困惑。
  • 你的意思是根据函数类型检查 addMethod 的第二个参数吗?我正在尝试实现一个流利的构建器,谢谢
  • @SteveHynding '''function JsClassFactory() { this.X = class { }; this.addMethod = function (name, def) { if (typeof def !== "function") throw Error('def must be a function type'); this.addAttribute(name, def) } this.addAttribute = function (name, def) { let Y = class extends this.X { constructor() { super() this[name] = def } } this.X = Y return这; } this.getClass = function () { return this.X }; }
  • 每次调用addMethod 都重复this.X = class extends this.X { … } 是可怕且低效的。只需使用this.X.prototype[name] = def;
  • 另外,属性应该在构造函数中添加,并且它们的值应该来自构造函数的参数。在工厂中添加它们,并为每个具有不同值的实例创建新类,这简直是可恶的。

标签: javascript class factory


【解决方案1】:

这是我将采取的方法来实现这一点。

class JSClassBuilder {
  constructor(){
    this.constructedClass = class {};
    this.constructedClassAttributes = {};
  }
  
  addStatic(name, definition){
    this.constructedClass[name] = definition;
    return this;
  }
  
  addAttribute(name, value){
    if(typeof definition != 'function'){
      this.constructedClassAttributes[name] = value;
      return this;
    }
    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;
    }
    throw new TypeError("parameter definition must be of type: 'function'");
  }
  
  constructClass(){
    return Object.assign(
      new this.constructedClass(), 
      this.constructedClassAttributes
    ); 
  }
}

const classBuilder = new JSClassBuilder();

const 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();

const a = classBuilder
            .addAttribute('name', 'Ali')
            .addAttribute('age', 15)
            .constructClass();
a.myName();
a.myAge();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-22
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 2021-09-30
    • 2020-10-20
    相关资源
    最近更新 更多