javascript - 创建一个接受对象文字的函数并从该对象的成员创建一个类

标签 javascript oop jsdoc

我的问题:

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类,它有2个实例方法(或者它们也可以是静态方法),它们是initialize。我想知道我们如何创建这种功能。

我想知道什么:

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

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

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

最佳答案

首先,您可以浏览一下 MDN docs on classes 。在那里您将找到一些重要的信息:

Classes are in fact just "special functions"

并且,解释一下:

Just as you can define function expressions ... you can define class expressions

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

有不止一种方法可以解决这个问题,但希望考虑到上面的示例,这是有意义的:

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!

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

I also want to know if this kind of creating class way is strange or not, or you can think the kind of function like makeClass is useful or not.

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

I want to ... understand the @lends tag of JSDoc.

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

The @lends tag tells JSDoc that all the member names of that object literal are being "loaned" to a variable named Person.

Person 变量是我们的类,用 @lends 注释对象文字告诉 JSDoc 我们正在“借出”初始化say成员。

关于javascript - 创建一个接受对象文字的函数并从该对象的成员创建一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68356205/

相关文章:

javascript - JQuery/HTML5 : Organisational Chart, 如何使用此插件正确删除节点?

javascript - ReactJS 与 firebase.add 未定义错误

c# - 为什么 C# 和 Java 要求所有内容都在一个类中?

dojo - 我应该如何使用 JSDoc 记录 Dojo getter 和 setter?

javascript - WebStorm对函数返回类型的类型识别的困惑

javascript - 找不到模块 'actions-on-google',正在使用 dialogflow

javascript - 检索图像的 HTML 元数据而不是下载图像

ios - 如何在 iOS 中初始化该协议(protocol)?

oop - 在编码之后还是之前创建UML图?

javascript - 如何使用 jdoc 描述接收具有动态属性(如 json 模式)的复杂对象的函数