-
Notifications
You must be signed in to change notification settings - Fork 25
/
index.js
45 lines (41 loc) · 1.39 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* ### .getFuncName(constructorFn)
*
* Returns the name of a function.
* When a non-function instance is passed, returns `null`.
* This also includes a polyfill function if `aFunc.name` is not defined.
*
* @name getFuncName
* @param {Function} funct
* @namespace Utils
* @api public
*/
const { toString } = Function.prototype;
const functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*/)]+\*\/\s*)*([^\s(/]+)/;
const maxFunctionSourceLength = 512;
function getFuncName(aFunc) {
if (typeof aFunc !== 'function') {
return null;
}
let name = '';
if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') {
// Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined
// eslint-disable-next-line prefer-reflect
const functionSource = toString.call(aFunc);
// To avoid unconstrained resource consumption due to pathalogically large function names,
// we limit the available return value to be less than 512 characters.
if (functionSource.indexOf('(') > maxFunctionSourceLength) {
return name;
}
const match = toString.call(aFunc).match(functionNameMatch);
if (match) {
[ name ] = match;
}
} else {
// If we've got a `name` property we just use it
// eslint-disable-next-line prefer-destructuring
name = aFunc.name;
}
return name;
}
export { getFuncName };