gpt4 book ai didi

javascript - 在 ES6 中创建带箭头或不带箭头的顶级函数的优缺点是什么?

转载 作者:行者123 更新时间:2023-12-03 22:36:51 25 4
gpt4 key购买 nike

以这些不同的方式在 ES6/ES2015 中创建顶级函数的优点/缺点是什么?或者这只是品味/风格指南等问题?

选项1:

function square(n) {
return n * n;
}

选项 2:
var square = function(n) {
return n * n;
};

选项 3:
var square = (n) => {
return n * n;
};

选项 4:
const square = (n) => {
return n * n;
};

最佳答案

注:我已将此作为社区维基发布,我们都可以添加到列表中,澄清等。请不要发表意见。 保持客观。

Or is this just a matter of taste/style guide etc?


是的,风格会有很大的影响,但是我们可以根据选项的功能和运行时特性进行一些客观的观察,这些观察可用于决定哪个适合给定的用例。

Option 1:

function square(n) {
return n * n;
}

  • 提升(因为它是一个函数声明)。
  • 在 ES2015 (ES6) 之前,仅在全局作用域或函数的顶层有效; ES2015+ 允许在控制流语句中使用它们,但规则很复杂。
  • 以后可以通过 square = ... 覆盖(或稍后的函数声明)。
  • 创建一个对象并将其分配给 square.prototype ,即使我们不打算将它作为构造函数。
  • 尝试将其用作构造函数 ( new square ) 会起作用,但可能不会按照编码人员的预期使用: new 的结果操作将是一个使用 square.prototype 的对象作为它的原型(prototype)(来自 n * n 的函数返回值被丢弃)。
  • 如果在全局范围内,则在全局对象(因此是全局对象)上创建一个属性,因为它是一个函数声明。
  • this在函数中使用,它将由函数的调用方式决定,因为它是一个“正常”函数。

  • Option 2:

    var square = function(n) {
    return n * n;
    };

  • 未提升(因为它是一个表达式),在控制流期间创建。
  • 在 ES2015 之前,由于它是一个匿名函数表达式,因此该函数没有名称。在 ES2015+ 中,名称源自变量的名称(浏览器支持可能有点滞后,在 ES2015 支持优先级列表中似乎较低)。
  • 以后可以通过 square = ... 覆盖
  • 创建一个对象并将其分配给 square.prototype ,即使我们不打算将它作为构造函数。
  • 尝试将其用作构造函数 ( new square ) 将起作用,但可能不会执行编码器的预期(请参阅函数声明的注释)。
  • 如果在全局范围内,则在全局对象(因此,全局对象)上创建一个属性,因为它是旧式 var多变的。
  • this在函数中使用,它将由函数的调用方式决定,因为它是一个“正常”函数。

  • Option 2.5: (I've added this one)

    var square = function square(n) {
    return n * n;
    };

    与选项 2 完全一样,除了在 ES5 及更早版本上,该函数具有真实名称 ( square )。 (请注意,名称不必与变量的名称相同,尽管在本示例中是这样。)(IE8 及更早版本中的错误最终会创建两个函数而不是一个;详细信息在 this blog post 中作者:TJ Crowder [这个答案的主要作者]。)

    Option 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 功能,您可以改用其余参数)。
  • 根据规范,调用它时需要“设置”的东西更少,因为它没有自己的 this并且没有 arguments .但是现代 JavaScript 引擎已经优化了 arguments 的创建如果您不使用它,则不太可能设置 this是一项重大成本。
  • 如果在全局范围内,则在全局对象(因此,全局对象)上创建一个属性,因为它是旧式 var多变的。
  • 因为是箭头函数,如果this在函数中使用,它将使用相同的 this作为定义函数的代码,因为箭头函数关闭了 this (而不是根据它们的调用方式来设置它)。

  • Option 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 (而不是根据它们的调用方式来设置它)。

  • Option 5: (I've added this one)

    let square = (n) => {
    return n * n;
    };

    也可以写成:
    let square = n => n * n;
    与选项 4 完全一样,不同之处在于它可以稍后通过 square = ... 覆盖。

    关于javascript - 在 ES6 中创建带箭头或不带箭头的顶级函数的优缺点是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38479859/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com