Ответ 1
Я проясню это здесь, любая произвольная функция может быть конструктором. Если вы различаете "класс" и "функцию", вы делаете неправильный выбор дизайна API. Если вы предполагаете, что что-то должно быть class
, например, никто не использует Babel или Typescript, будет обнаружен как class
, потому что вместо этого код будет преобразован в функцию. Это означает, что вы требуете, чтобы кто-либо, использующий вашу кодовую базу, должен работать в среде ES6 в целом, поэтому ваш код будет непригоден для старых сред.
Ваши параметры здесь ограничены поведением, определяемым реализацией. В ES6, когда код разобран и синтаксис обрабатывается, осталось мало изменений в классе. Все, что у вас есть, - это функция-конструктор. Ваш лучший выбор - сделать
if (typeof Thingy === 'function'){
// It a function, so it definitely can't be an instance.
} else {
// It could be anything other than a constructor
}
и если кто-то должен выполнить функцию не-конструктора, выведите для него отдельный API.
Очевидно, что это не тот ответ, который вы ищете, но важно сделать это понятным.
Как упоминается здесь в другом ответе, у вас есть опция, потому что для возврата декларации класса требуется .toString()
для функций, например.
class Foo {}
Foo.toString() === "class Foo {}" // true
Главное, однако, в том, что это применимо только в том случае, если это возможно. Это соответствует 100% -ной спецификации для реализации,
class Foo{}
Foo.toString() === "throw SyntaxError();"
В настоящее время нет браузеров, но есть несколько встроенных систем, которые сосредоточены на JS-программировании, например, и для сохранения памяти для самой вашей программы, они отбрасывают исходный код после его анализа, то есть у них не будет исходного кода для возврата из .toString()
, и это разрешено.
Аналогично, используя .toString()
, вы делаете предположения как о будущей проверке, так и об общем дизайне API. Скажите, что вы делаете
const isClass = fn => /^\sclass/.test(fn.toString());
потому что это зависит от строковых представлений, оно может легко сломаться.
Возьмите декораторы, например:
@decorator class Foo {}
Foo.toString() == ???
Входит ли .toString()
из этого декоратора? Что, если сам декоратор возвращает function
вместо класса?