由于ES5不支持Function#name
。我一直在寻找一种模拟该功能的方法。许多人建议使用Function#name
,但强烈建议其他人不要使用。
那么使用下面的代码获取函数名称会有什么风险?
Function#toString
由于ES5不支持Function#toString
,所以我真的看不出风险在何时。
正如if (!Object.hasOwnProperty(Function.prototype, "name")) {
Object.defineProperty(Function.prototype, "name", {
configurable: false,
enumerable: true,
get: function() {
var result = /function\s+(\w(?:\w|\d)*)\(/.exec(this.toString());
return result ? result[1] : "";
}
});
}
所说,arrow functions方法返回的语法为ECMAScript 5.1 specification的字符串:
Function.prototype.toString()
返回与实现有关的函数表示形式。此表示具有FunctionDeclaration的语法。请特别注意,在表示形式String中,空格,行终止符和分号的使用和放置取决于实现。
toString
函数不是通用的;如果其this值不是Function对象,则抛出TypeError异常。因此,不能将其传递给其他类型的对象以用作方法。
FunctionDeclaration具有以下语法:
FunctionDeclaration:
功能 标识符 ( FormalParameterList opt ){ FunctionBody }
FormalParameterList:
标识符FormalParameterList , 标识符
和FunctionDeclaration定义如下:
标识符 ::
IdentifierName 但不是 ReservedWord
IdentifierName ::
IdentifierStartIdentifierName IdentifierPart
IdentifierStart ::
UnicodeLetter$_\ UnicodeEscapeSequence
IdentifierPart ::
IdentifierStartUnicodeCombiningMarkUnicodeDigitUnicodeConnectorPunctuation
虽然不是获得函数名称的好方法(但在ES5中是only way,但是如果您解析它上面列出的所有可能性,它可以在ES5中安全地工作。
但是ES6标准修改了toString
的规范,这暗示了更多可能的语法,使其在其中使用此方法不安全。
因此,仅在ES6之前的版本中使用此方法。