【问题标题】:Create a function that takes an object literal and create a class from that object's members创建一个接受对象字面量的函数并从该对象的成员创建一个类
【发布时间】:2021-07-23 05:28:43
【问题描述】:

我的问题:

var Person = makeClass( // Make a class with 2 instance methods which are initialize and say 
    {
        initialize: function(name) {
            this.name = name;
        },
        say: function(message) {
            return this.name + " says: " + message;
        }
    }
);

documentation of the @lends tag of jsdoc 中,我发现他们正在使用一个辅助函数,他们说它可以接受一个对象字面量并从该对象的成员创建一个类。在上面的例子中,makeClass 函数创建了一个Person 类,它有两个实例方法(或者它们也可以是静态方法),它们是initializesay。我想知道我们是如何创建这种函数的。

我想知道的:

我试图重新创建那种功能,但对我来说真的很难,我不知道有什么办法可以做到。所以希望你们能给我一个重新创建这个makeClass函数的方法。
我也想知道这种创建类的方式是不是很奇怪,或者你可以认为makeClass这种函数有用与否。

我为什么要创建那个函数的原因:

如果你问我原因,我想知道函数里面的“成分”,以便理解JSDoc的@lends标签,我想真正了解这个@lends标签的用例在JSDoc。但是面对这种奇怪的创建类的方式(对我来说很奇怪,我以前总是使用 ES6 类)我真的很难理解@lends 标签。

【问题讨论】:

    标签: javascript oop jsdoc


    【解决方案1】:

    首先,您可以查看 MDN docs on classes。在那里你会发现一些重要的信息:

    类实际上只是“特殊功能”

    而且,稍微解释一下:

    就像你可以定义函数表达式...你可以定义类表达式

    所以,如果类表达式可以以与函数表达式相同的方式创建,而类只是“特殊函数”,那么暂停一下并问自己可能会更容易:我们如何编写函数创建一个函数

    有不止一种方法可以解决,但希望从上面的示例来看这是有道理的:

    const makeFunction = function(valToAdd) {
      return function(val) {
        return val + valToAdd;
      }
    }
    
    const addTwo = makeFunction(2);
    addTwo(2)  // 4
    

    现在,将makeFunction 翻译成makeClass 希望更简单一些。范例是相同的,但我们需要做更多的工作来创建实例方法:

    const makeClass = function(obj) {
      // Anonymous class expression
      const dynamicClass = class {};
      
      // Define properties on our class
      for (const [name, value] of Object.entries(obj)) {
        // Notice we define properties on the prototype so instances of the class can access them
        Object.defineProperty(dynamicClass.prototype, name, {
          value,
          writable: true,
          configurable: true
        })
      }
      return dynamicClass;
    }
    
    // Create a Person class with methods `initialize` and `say`
    const Person = makeClass({
      initialize: function(name) {
        this.name = name;
      },
      say: function(message) {
        return this.name + " says: " + message;
      }
    })
    
    // Create an instance
    const person = new Person()
    
    person.initialize("Sam")
    person.say("Hello!") // Sam says: Hello!
    

    并回答您的一些具体问题:

    我也想知道这种创建类的方式是不是很奇怪,或者你可以认为像makeClass这样的函数有没有用。

    我认为这是一种创建类的奇怪方式,尽管在某些用例中它可能很有用。一般来说,这种范式称为metaprogramming,通常用于整合共享功能。权衡是复杂性很容易膨胀,并让其他使用您的代码的人感到困惑。

    我想……了解一下JSDoc的@lends标签。

    由于makeClass 创建实例方法的方式(它本质上是复制它们),JSDoc 不了解创建的类可以使用哪些方法。所以这现在应该是有意义的(来自JSDoc 文档):

    @lends 标记告诉 JSDoc,该对象字面量的所有成员名称都“借给”了一个名为 Person 的变量。

    Person 变量是我们的类,用 @lends 注释对象字面量告诉 JSDoc 我们正在“借给”initializesay 成员给它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-31
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-13
      相关资源
      最近更新 更多