由于 ES5 不支持Function#name
.我一直在寻找一种模拟该功能的方法。虽然很多人建议使用Function#toString
,但其他人强烈建议不要这样做。
那么使用以下代码获取函数名称有什么风险呢?
if (!Object.hasOwnProperty(Function.prototype, "name")) {
Object.defineProperty(Function.prototype, "name", {
configurable: false,
enumerable: true,
get: function() {
var result = /functions+([^s(]+)/.exec(this.toString());
return result ? result[1] : "";
}
});
}
由于 ES5 不支持箭头功能,我真的看不出风险在哪里。
正如 ECMAScript 5.1 规范所说,toString
方法返回一个具有FunctionDeclaration语法的字符串:
Function.prototype.toString ( (
返回函数的依赖于实现的表示形式。此表示形式具有FunctionStatement的语法。特别要注意的是,在表示字符串中使用和放置空格、行终止符和分号取决于实现。
toString
函数不是泛型的;如果此值不是 Function 对象,则会引发TypeError异常。因此,它不能转移到其他类型的对象以用作方法。
函数声明具有以下语法:
功能声明:
函数 标识符 ( FormalParameterList opt ( { FunctionBody }
形式参数列表:
标识符形式参数列表,标识符
和标识符定义如下:
标识符::
标识符名称 ,但不是 保留字
标识符名称::
标识符开始
标识符名称标识符部分标识符开始::
UnicodeLetter
$
_
\UnicodeEscapeSequence标识符部分::
标识符开始
UnicodeCombiningMark
UnicodeDigit
UnicodeConnector 标点符号
结论
虽然这不是获取函数名称的好方法(但这是 ES5 中的唯一方法(,但如果你让它解析上面列出的所有可能性,它可以在 ES5 中安全地工作。
但是ES6标准修改了.toString()
的规范,这意味着更多可能的语法,使得在其中使用这种方法是不安全的。
因此,仅在 ES6 之前的版本中使用此方法。