Каковы риски использования toString для получения имени функции? - PullRequest
3 голосов
/ 12 октября 2019

Поскольку 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 не поддерживает функции стрелок , я не вижу, где находится риск.

1 Ответ

1 голос
/ 12 октября 2019

Как указано в спецификации ECMAScript 5.1 , метод toString возвращает строку с синтаксисом FunctionDeclaration :

Function.prototype.toString ()

Возвращается зависящее от реализации представление функции. Это представление имеет синтаксис FunctionDeclaration . В частности, обратите внимание, что использование и размещение пробелов, ограничителей строки и точек с запятой в представлении String зависит от реализации.

Функция toString не является универсальной;он генерирует исключение TypeError , если его это значение не является объектом Function. Поэтому его нельзя передавать другим объектам для использования в качестве метода.

FunctionDeclaration имеет следующий синтаксис:

FunctionDeclaration :

function Идентификатор ( FormalParameterList opt ) { FunctionBody }

FormalParameterList :

Идентификатор
FormalParameterList , Идентификатор

И Идентификатор определяется как:

Идентификатор ::

Имя_идентификатора , но не ReservedWord

IdentifierName ::

IdentifierStart
IdentifierNameIdentifierPart

IdentifierStart ::

UnicodeLetter
$
_
\ UnicodeEscapeSequence

IdentifierPart ::

IdentifierStart
UnicodeCombiningMark
UnicodeDigit
UnicodeConnectorPunctuation

Заключение

Хотя это не прекрасный способ получить имя функции (но только в ES5), если вы выполните анализ всех перечисленных выше возможностей, он может безопасно работать в ES5.

Но стандарт ES6 изменил спецификации для .toString(), что подразумевает больше возможных синтаксисов, сделав егонебезопасно использовать этот метод в нем.

Таким образом, используйте этот метод только в версиях до ES6.

...