注意:我已将此作为社区维基发布,我们都可以添加到列表中,澄清等。请不要发表意见。保持客观。
或者这只是品味/风格指南等问题?
是的,风格会有很大的影响,但是我们可以根据选项的功能和运行时特性进行一些客观的观察,这些观察可用于决定哪个适合给定的用例。
选项1:
function square(n) {
return n * n;
}
- 提升(因为它是一个函数声明)。
- 在 ES2015 (ES6) 之前,仅在全局作用域或函数的顶层有效;ES2015+ 允许在控制流语句中使用它们,但规则很复杂。
- 以后可以通过
square = ...(或以后的函数声明)覆盖。
- 创建一个对象并将其分配给
square.prototype,即使我们不打算将它作为构造函数。
- 尝试将它用作构造函数 (
new square) 会起作用,但可能不会像编码人员所期望的那样:new操作的结果将是一个square.prototype用作其原型的对象(并且函数的返回值 fromn * n被丢弃)。
- 如果在全局范围内,则在全局对象(因此是全局对象)上创建一个属性,因为它是一个函数声明。
- 如果
this在函数内使用,它将由函数的调用方式决定,因为它是一个“正常”函数。
选项 2:
var square = function(n) {
return n * n;
};
- 未提升(因为它是一个表达式),在控制流期间创建。
- 在 ES2015 之前,由于它是一个匿名函数表达式,因此该函数没有名称。在 ES2015+ 中,名称来源于变量的名称(浏览器支持可能有点滞后,在 ES2015 支持优先级列表中似乎较低)。
- 以后可以通过覆盖
square = ...
- 创建一个对象并将其分配给
square.prototype,即使我们不打算将它作为构造函数。
- 尝试将其用作构造函数 (
new square) 会起作用,但可能不会达到编码人员的预期(请参阅函数声明的注释)。
- 如果在全局范围内,则在全局对象(因此是全局对象)上创建一个属性,因为它是一个旧式
var变量。
- 如果
this在函数内使用,它将由函数的调用方式决定,因为它是一个“正常”函数。
选项 2.5:(我已经添加了这个)
var square = function square(n) {
return n * n;
};
与选项 2 完全一样,除了在 ES5 及更早版本中,该函数具有真实名称 ( square)。(请注意,名称不必与变量的名称相同,尽管在本示例中是这样。)(IE8 及更早版本中的错误最终会创建两个函数而不是一个;详细信息请参阅此博客文章作者:TJ Crowder [这个答案的主要作者]。)
选项 3:
var square = (n) => {
return n * n;
};
也可以写成:
var square = n => n * n;
- 未提升(因为它是一个表达式),在控制流期间创建。
- 函数名来源于变量名(浏览器支持可能有点滞后,在 ES2015 支持优先级列表中似乎较低)。
- 以后可以通过覆盖
square = ...
- 不创建对象并将其分配给
square.prototype.
- 尝试将其用作构造函数 (
new square) 将失败并显示信息性错误 ( TypeError: square is not a constructor)。
- 没有
arguments(但如果需要arguments功能,您可以使用 rest 参数)。
- 根据规范,调用它时需要“设置”的东西更少,因为它没有自己的
this,也没有arguments. 但是arguments如果你不使用它,现代 JavaScript 引擎已经优化了它的创建,并且它不太可能this是一个巨大的成本。
- 如果在全局范围内,则在全局对象(因此是全局对象)上创建一个属性,因为它是一个旧式
var变量。
- 因为它是一个箭头函数,如果
this在函数内使用,它将使用与this定义函数的代码相同的代码,因为箭头函数关闭 this(而不是通过它们的调用方式设置它)。
选项 4:
const square = (n) => {
return n * n;
};
也可以写成:
const square = n => n * n;
- 未提升,在控制流期间创建
- 函数名来源于变量名(浏览器支持可能有点滞后,在 ES2015 支持优先级列表中似乎较低)。
- 以后不能被覆盖通过
square = ...
- 不创建对象并将其分配给
square.prototype.
- 尝试将其用作构造函数 (
new square) 将失败并显示信息性错误 ( TypeError: square is not a constructor)。
- 没有
arguments(参见选项 3 的注释)。
- 根据规范,调用它时需要“设置”的东西更少(参见选项 3 的注释)。
- 如果在全局范围内,则不会在全局对象上创建属性(但仍会创建全局对象),因为它是 ES2015+
const。
- 因为它是一个箭头函数,如果
this在函数内使用,它将使用与this定义函数的代码相同的代码,因为箭头函数关闭 this(而不是通过它们的调用方式设置它)。
选项5:(我已经添加了这个)
let square = (n) => {
return n * n;
};
也可以写成:
let square = n => n * n;
与选项 4 完全一样,只是以后可以通过 square = ...