不要忘记命名表达式 - 匿名函数会使在错误的调用堆栈中定位问题变得更加困难(讨论)
原答案如下
MDN 对函数名称推断的工作原理有很好的了解,包括两个警告:
观察
以下两种情况下存在非标准<function>.name
推理行为:
- 使用脚本解释器时
只有当函数没有自己的名为 name 的属性时,脚本解释器才会设置函数的 name 属性...
- 使用js工具时
使用 Function.name 和源代码转换时要小心,例如由 JavaScript 压缩器(压缩器)或混淆器执行的转换
……
在未压缩版本中,程序运行到truthy-branch 并记录'foo' 是'Foo' 的一个实例,而在压缩版本中它的行为不同并运行到else-branch。因此,如果您像上面的示例一样依赖 Function.name,请确保您的构建管道不会更改函数名称或不假定函数具有特定名称。
什么是函数名推断?
该name
属性返回函数的名称,或者(在 ES6 实现之前)匿名函数的空字符串
function doSomething() {}
console.log(doSomething.name); // logs "doSomething"
使用语法 new Function(...) 或仅 Function(...) 创建的函数将其 name 属性设置为空字符串。在以下示例中创建了匿名函数,因此 name 返回一个空字符串
var f = function() {};
var object = {
someMethod: function() {}
};
console.log(f.name == ''); // true
console.log(object.someMethod.name == ''); // also true
实现 ES6 函数的浏览器可以从其句法位置推断出匿名函数的名称。例如:
var f = function() {};
console.log(f.name); // "f"
观点
出于三个基本原因,我个人更喜欢分配给变量的(箭头)函数:
首先,我从不使用function.name
其次,将命名函数的词法范围与赋值混合起来感觉有点松散:
// This...
function Blah() {
//...
}
Blah.propTypes = {
thing: PropTypes.string
}
// ...is the same as...
Blah.propTypes = {
thing: PropTypes.string
}
function Blah() {
//...
}
// ALTERNATIVELY, here lexical-order is enforced
const Blah = () => {
//...
}
Blah.propTypes = {
thing: PropTypes.string
}
第三,在所有条件相同的情况下,我更喜欢箭头函数:
- 与读者交流没有
this
,没有arguments
等
- 看起来更好(恕我直言)
- 性能(我上次看时,箭头函数略快)
编辑:内存快照
我正在听一个播客,客人告诉我他必须处理使用箭头函数和内存分析的限制,我以前也遇到过完全相同的情况。
目前,内存快照不包含变量名称 - 因此您可能会发现自己将箭头函数转换为命名函数只是为了连接内存分析器。我的经验非常简单,我仍然对箭头功能感到满意。
另外,我只使用过一次内存快照,因此默认情况下,为了(主观)清晰而放弃一些“工具”,我感到很自在。