Если по сравнению со скоростью переключателя

Джастин Фагнани описывает очень чистый (imho) способ составления нескольких классов в один, используя тот факт, что в ES2015 классы могут быть созданы с помощью выражений класса .

Выражения против деклараций

В принципе, так же, как вы можете создать функцию с выражением:

function myFunction() {}      // function declaration
var myFunction = function(){} // function expression

, вы можете сделать то же самое с классами:

class MyClass {}             // class declaration
var MyClass = class {}       // class expression

Выражение оценивается во время выполнения, когда код выполняется, тогда как объявление выполняется заранее.

Использование выражений класса для создания mixins

Вы можете использовать это для создайте функцию, которая динамически создает класс только при вызове функции:

function createClassExtending(superclass) {
  return class AwesomeClass extends superclass {
    // you class body here as usual
  }
}

Приятная вещь в том, что вы можете заранее определить весь класс и только решить, какой класс он должен распространять на время, когда вы вызываете функцию:

class A {}
class B {}
var ExtendingA = createClassExtending(A)
var ExtendingB = createClassExtending(B)

Если вы хотите объединить несколько классов вместе, поскольку классы ES6 поддерживают только одно наследование, вам необходимо создать цепочку классов, которая содержит все классы, которые вы используете муравей смешивать вместе. Итак, скажем, вы хотите создать класс C, который расширяет оба A и B, вы могли бы сделать это:

class A {}
class B extends A {}
class C extends B {}  // C extends both A and B

Проблема в том, что он очень статичен. Если вы позже решите, что хотите сделать класс D, который расширяет B, но не A, у вас есть проблема.

. Но с помощью некоторых умных обманщиков, используя тот факт, что классы могут быть выражениями, вы можете решить это, создав A и B не непосредственно как классы, а как классные заводы (с использованием функций стрелок для краткости):

class Base {} // some base class to keep the arrow functions simple
var A = (superclass) => class A extends superclass
var B = (superclass) => class B extends superclass
var C = B(A(Base))
var D = B(Base)

Обратите внимание, как мы решаем в последний момент, какие классы включать в иерархию.

Помогите нам построить будущее!

Конечно, если вы похожи на меня, это вдохновляет вас на создание окончательной библиотеки для множественного наследования в Javascript. Если вы это сделаете, пожалуйста, помогите мне сделать именно это!

mics

mics (произносится: mix) - это библиотека, которая делает множественное наследование в Javascript - легкий ветерок. Вдохновленный отличным сообщением в блоге «Реальные» миксины с Javascript-классами Джастином Фагнани, mics пытается создать минимальную библиотеку вокруг концепции использования выражений класса (фабрик) в качестве mixins. mics расширяет концепции, представленные в блоге, создавая микшинов первоклассных граждан, которые могут быть непосредственно использованы для создания объектов и могут быть смешаны с другими миксинами, а не просто с классами.

blockquote>

108
задан Dirk Vollmar 14 January 2009 в 23:13
поделиться

5 ответов

Компилятор может создать таблицы переходов когда это применимо. Например, при использовании отражателя для рассмотрения произведенного кода, Вы будете видеть, что для огромных переключателей на строках, компилятор на самом деле генерирует код, который использует хэш-таблицу для диспетчеризации их. Хэш-таблица использует строки в качестве ключей и делегатов в case коды как значения.

Это имеет асимптотическое лучшее время выполнения, чем много цепочечных if тесты и на самом деле быстрее даже для относительно немногих строк.

178
ответ дан Konrad Rudolph 5 November 2019 в 10:26
поделиться

Konrad корректен. В случае включения непрерывных диапазонов целых чисел (например, где у Вас есть случай 0, случай 1, случай 2.. случай n), компилятор может сделать что-то еще лучше, потому что это не должно даже создавать хэш-таблицу; это просто хранит массив указателей функции, и таким образом может загрузить его цель перехода в постоянное время.

29
ответ дан Community 3 July 2019 в 15:40
поделиться

Поскольку Konrad сказал, что компилятор может создать Таблицу переходов.

В C++ причина это банка из-за ограничения переключателей.

5
ответ дан J.J. 3 July 2019 в 15:40
поделиться

Это - небольшое упрощение как обычно любой современный компилятор, который встречается if..else if .. последовательность, которая могла тривиально быть преобразована в оператор переключения человеком, компилятор будет также. Но только добавить дополнительную забаву компилятор не ограничивается синтаксисом, так может генерировать "переключатель" как операторы внутренне, которые имеют соединение диапазонов, единых целей, и т.д. - и они могут (и делать), делают это и для переключателя и для если.. еще операторы.

Anyhoo, расширение ответа Konrad состоит в том, что компилятор может генерировать таблицу переходов, но это не обязательно гарантировало (ни желательный). По ряду причин таблицы переходов делают плохие вещи к предикторам ответвления на современных процессорах, и сами таблицы делают плохие вещи кэшировать поведение, например,

switch(a) { case 0: ...; break; case 1: ...; break; }

, Если бы компилятор на самом деле генерировал таблицу переходов для этого, то это, вероятно, было бы медленнее что альтернатива if..else if.. код стиля из-за таблицы переходов, побеждающей предсказание ветвлений.

14
ответ дан olliej 5 November 2019 в 10:26
поделиться

Статистика без соответствия не может быть хорошей.

при фактической загрузке источника никакие значения соответствия, как не известно, 21 в обоих если и случай переключателя. Компилятор должен быть в состоянии абстрагировать далеко, зная, какой оператор должен быть выполнен в любом случае, и ЦП должен быть в состоянии перейти, предсказывают правильно.

более интересный случай является если не каждым случаем повреждения, по-моему, но это не могло быть объемом эксперимента.

4
ответ дан Calyth 5 November 2019 в 10:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: