使用 toString 获取函数名称有什么风险?
What are the risks of using toString to get the name of a function?
由于ES5不支持Function#name
. I was looking for a way to emulate that functionality. While a lot of people recommend using 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不支持arrow functions,所以我真的看不出风险在哪里。
作为 ECMAScript 5.1 specification says, the toString
method returns a string that has the syntax of FunctionDeclaration:
Function.prototype.toString ( )
An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration. Note in particular that the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.
The toString
function is not generic; it throws a TypeError exception if its this value is not a Function object. Therefore, it cannot be transferred to other kinds of objects for use as a method.
FunctionDeclaration 具有以下语法:
FunctionDeclaration :
function Identifier ( FormalParameterListopt ) { FunctionBody }
FormalParameterList :
Identifier
FormalParameterList , Identifier
和Identifier定义如下:
Identifier ::
IdentifierName but not ReservedWord
IdentifierName ::
IdentifierStart
IdentifierName IdentifierPart
IdentifierStart ::
UnicodeLetter
$
_
\ UnicodeEscapeSequence
IdentifierPart ::
IdentifierStart
UnicodeCombiningMark
UnicodeDigit
UnicodeConnectorPunctuation
结论
虽然这不是一个很好的获取函数名的方法(但是 ES5 中唯一的方法),如果你让它解析上面列出的所有可能性,它可以在 ES5 中安全工作。
但是ES6标准修改了.toString()
的规范,这意味着更多可能的语法,使得在其中使用这种方法是不安全的。
所以,只在ES6之前的版本使用此方法
由于ES5不支持Function#name
. I was looking for a way to emulate that functionality. While a lot of people recommend using 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不支持arrow functions,所以我真的看不出风险在哪里。
作为 ECMAScript 5.1 specification says, the toString
method returns a string that has the syntax of FunctionDeclaration:
Function.prototype.toString ( )
An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration. Note in particular that the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.
The
toString
function is not generic; it throws a TypeError exception if its this value is not a Function object. Therefore, it cannot be transferred to other kinds of objects for use as a method.
FunctionDeclaration 具有以下语法:
FunctionDeclaration :
function Identifier ( FormalParameterListopt ) { FunctionBody }
FormalParameterList :
Identifier
FormalParameterList , Identifier
和Identifier定义如下:
Identifier ::
IdentifierName but not ReservedWord
IdentifierName ::
IdentifierStart
IdentifierName IdentifierPartIdentifierStart ::
UnicodeLetter
$
_
\ UnicodeEscapeSequenceIdentifierPart ::
IdentifierStart
UnicodeCombiningMark
UnicodeDigit
UnicodeConnectorPunctuation
结论
虽然这不是一个很好的获取函数名的方法(但是 ES5 中唯一的方法),如果你让它解析上面列出的所有可能性,它可以在 ES5 中安全工作。
但是ES6标准修改了.toString()
的规范,这意味着更多可能的语法,使得在其中使用这种方法是不安全的。
所以,只在ES6之前的版本使用此方法