2016-10-15 2 views
1

Если я хочу динамически создавать новые классы (а не экземпляры) на лету в EcmaScript, как я могу это сделать? И как могут эти экземпляры extend из другого класса?Как создать классы EcmaScript на лету?

Традиционно можно сделать "класс":

function Living(){} 
Living.prototype.eat = function(){ console.log("eat") } 

Затем динамически продлить его:

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 

И так далее:

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 

Ключ является то, что я хотите сделать это динамически, с учетом данных. Этот традиционный подход давайте мне динамически создавать новые классы:

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

И таким образом я могу динамически, данное drivenly создать классы мне нужно.

Теория Мне показалось, что мне сказали, что классы EcmaScript были просто синтаксическим сахаром и что я могу продолжать использовать старый синтаксис. Однако мы начинаем видеть примеры, в которых будут выполняться только классы EcmaScript (например, Custom Elements), и поэтому эта способность «на лету» определять новые классы (в отличие от использования выражения класса, которое представляет собой статическое строительство) становится важным.

В пользовательских элементов нуждаясь новый выпуск class синтаксиса, Доменик Denicola пишет

Я надеюсь, что вы знаете, что вы можете создавать классы динамически так же легко, как функции,

И я Как бы спросить, как? Если мне нужен новый класс, который расширяет HTMLElement, как я могу создать его «на лету», управляемым данными?

+0

Обратите внимание, что вы все равно можете определить пользовательские элементы, используя синтаксис «old». – Supersharp

ответ

6

Используйте class expression:

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' 

Суперкласс здесь (Living), может быть заменен на что-либо, так как это выражение (Living, в конце концов, так же, как и любая другая переменная).

Это говорит о том, что я постараюсь избежать динамического создания классов, если это возможно, и вместо этого использовать экземпляры.

+1

Andrew: у вас нет * динамически * созданного класса, вы создали выражение класса, которое может быть сделано только * статически. * Если у меня есть таблица Живых вещей, я хочу создавать подклассы, выражения класса будут делать меня статически введите каждый из них. – rektide

+2

@rektide Неверно (если «динамический» означает что-то другое для вас). См. Мое редактирование. Ваш оригинальный пример не включал цикл, поэтому я не был в моем. Надеюсь, теперь с ним стало ясно. –

+0

@rektide вы путаете класс _declarations_ (статический) с классом _expressions_. – joews

Смежные вопросы