如何动态创建EcmaScript类?

rek*_*ide 1 javascript class dynamic custom-element

如果我想在EcmaScript中动态创建新类(而不是实例),我该怎么做?那些extend来自另一个班级的实例怎么样?

传统上,人们可以成为"阶级":

function Living(){}
Living.prototype.eat = function(){ console.log("eat") }
Run Code Online (Sandbox Code Playgroud)

然后动态扩展它:

function makeSubclass(name, parentClass){
  var klass = new Function()
  klass.name = name
  klass.displayName = name
  klass.prototype = parentClass.prototype
  klass.prototype.constructor = klass
}
var Animal = makeSubclass("Animal", Living)
var dog = new Animal()
dog.eat() //=> eat
Run Code Online (Sandbox Code Playgroud)

等等:

Animal.prototype.walk = function(){ console.log("one foot then another") }
var Person = makeSubclass("Person", Animal)
var rektide = new Person()
rektide.eat() //=> eat
rektide.walk() //=> one foot then another
Run Code Online (Sandbox Code Playgroud)

关键是我希望以数据驱动的方式动态地这样做.这种传统方法让我动态创建新类:

fetch("http://yoyodyne.net/animals").then(response => response.json()).then(animals => {
    animals.forEach(animalName => window[animalName] = makeSubclass(animalName, Animal)
})
Run Code Online (Sandbox Code Playgroud)

因此我可以动态地,数据驱动地创建我需要的类.

我以为我被告知的理论是,EcmaScript类只是语法糖,我可以继续使用旧语法.但是我们开始看到只有EcmaScript类会做的例子(例如自定义元素),因此这种动态定义新类的能力(与使用类表达式相反,这是一种静态结构)变得很重要.

在需要新class语法问题的自定义元素中,Domenic Denicola写道

我希望你知道你可以像动作一样动态地生成类,

所以我想问一下,怎么样?如果我想要一个扩展HTMLElement的新类,我怎样才能以数据驱动的方式动态创建它?

And*_*all 6

使用类表达式:

class Living {
  eat() {
    return 42
  }
}

const livingThings = {}
;['dog', 'cat'].forEach((name) => (
  livingThings[name] = class extends Living {
    name() { return name }
  }
))

const myDog = new livingThings.dog()
myDog.eat()  //=> 42
myDog.name() //=> 'dog'
Run Code Online (Sandbox Code Playgroud)

这里的超类(Living)可以替换为任何东西,因为它是一个表达式(Living毕竟,就像任何其他变量一样).

也就是说,如果可能的话,我会尽量避免动态创建类,而是使用实例.

  • @rektide不正确(除非"动态"表示与您不同的东西).看我的编辑.你的原始例子没有包含循环,所以我没有在我的.希望它现在更加清晰. (2认同)