不要忘记命名表达式 - 匿名函数会使在错误的调用堆栈中定位问题变得更加困难(讨论)
原答案如下
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
等
- 看起来更好(恕我直言)
- 性能(上次我看,箭头函数稍微快一点)
编辑:内存快照
我正在听一个播客,客人告诉我他必须处理使用带有内存分析的箭头函数的限制的情况,我以前也遇到过完全相同的情况。
目前,内存快照不包含变量名称 - 因此您可能会发现自己将箭头函数转换为命名函数只是为了连接内存分析器。我的经验非常简单,我仍然对箭头函数感到满意。
另外,我只使用过一次内存快照,所以我觉得默认情况下放弃一些(主观)清晰度的“工具”很舒服。