3

由于 ES5 不支持Function#name. 我正在寻找一种模拟该功能的方法。虽然很多人建议使用Function#toString,但其他人强烈建议不要使用它。

那么使用下面的代码获取函数名有什么风险呢?

if (!Object.hasOwnProperty(Function.prototype, "name")) {
  Object.defineProperty(Function.prototype, "name", {
    configurable: false,
    enumerable: true,
    get: function() {
      var result = /function\s+([^\s(]+)/.exec(this.toString());
      return result ? result[1] : "";
    }
  });
}

由于 ES5 不支持箭头函数,我真的不知道什么时候有风险。

4

1 回答 1

1

正如ECMAScript 5.1 规范所说,该toString方法返回一个具有FunctionDeclaration语法的字符串:

函数.prototype.toString()

返回函数的依赖于实现的表示。此表示具有FunctionDeclaration的语法。请特别注意,在表示字符串中使用和放置空格、行终止符和分号是依赖于实现的。

toString功能不是通用的;如果this值不是 Function 对象,它会抛出TypeError异常。因此,它不能转移到其他种类的对象中用作方法。

FunctionDeclaration具有以下语法:

功能声明

函数 标识符 FormalParameterList opt ){ FunctionBody }

形式参数列表

标识符
FormalParameterList , 标识符

标识符定义如下:

标识符::

IdentifierName 但不是 ReservedWord

标识符名称::

IdentifierStart
IdentifierName IdentifierPart

标识符开始::

Unicode字母
$
_
\ UnicodeEscapeSequence

标识符部分::

IdentifierStart
UnicodeCombiningMark
UnicodeDigit
UnicodeConnectorPunctuation

结论

虽然它不是获取函数名的好方法(但在 ES5 中是唯一的方法),但如果你让它解析上面列出的所有可能性,它可以在 ES5 中安全地工作。

但是 ES6 标准修改了 的规范.toString(),这意味着更多可能的语法,使得在其中使用这种方法是不安全的。

因此,仅在 ES6 之前的版本中使用此方法。

于 2019-10-12T09:26:46.127 回答