UNPKG

1.8 kBJavaScriptView Raw
1'use strict';
2var uncurryThis = require('../internals/function-uncurry-this');
3var fails = require('../internals/fails');
4var isCallable = require('../internals/is-callable');
5var classof = require('../internals/classof');
6var getBuiltIn = require('../internals/get-built-in');
7var inspectSource = require('../internals/inspect-source');
8
9var noop = function () { /* empty */ };
10var construct = getBuiltIn('Reflect', 'construct');
11var constructorRegExp = /^\s*(?:class|function)\b/;
12var exec = uncurryThis(constructorRegExp.exec);
13var INCORRECT_TO_STRING = !constructorRegExp.test(noop);
14
15var isConstructorModern = function isConstructor(argument) {
16 if (!isCallable(argument)) return false;
17 try {
18 construct(noop, [], argument);
19 return true;
20 } catch (error) {
21 return false;
22 }
23};
24
25var isConstructorLegacy = function isConstructor(argument) {
26 if (!isCallable(argument)) return false;
27 switch (classof(argument)) {
28 case 'AsyncFunction':
29 case 'GeneratorFunction':
30 case 'AsyncGeneratorFunction': return false;
31 }
32 try {
33 // we can't check .prototype since constructors produced by .bind haven't it
34 // `Function#toString` throws on some built-it function in some legacy engines
35 // (for example, `DOMQuad` and similar in FF41-)
36 return INCORRECT_TO_STRING || !!exec(constructorRegExp, inspectSource(argument));
37 } catch (error) {
38 return true;
39 }
40};
41
42isConstructorLegacy.sham = true;
43
44// `IsConstructor` abstract operation
45// https://tc39.es/ecma262/#sec-isconstructor
46module.exports = !construct || fails(function () {
47 var called;
48 return isConstructorModern(isConstructorModern.call)
49 || !isConstructorModern(Object)
50 || !isConstructorModern(function () { called = true; })
51 || called;
52}) ? isConstructorLegacy : isConstructorModern;