在 ES6 中创建带箭头或不带箭头的顶级函数的优缺点是什么? [英] What are the advantages/disadvantages for creating a top level function in ES6 with arrows or without?

查看:23
本文介绍了在 ES6 中创建带箭头或不带箭头的顶级函数的优缺点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What are the advantages/disadvantages to create a top level function in ES6/ES2015 in those different ways? Or is this just a matter of taste/style guide etc?

选项 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;
};

推荐答案

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

Note: I've posted this as a community wiki, we can all add to the list, clarify, etc. Please no opinions. Keep it objective.

或者这只是品味/风格指南等问题?

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

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

There will be a strong influence of style, yes, but there are some objective observations we can make in terms of the functionality and runtime characteristics of the options that can be used to decide which is appropriate for a given use-case.

选项 1:

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

  • 提升(因为它是一个函数声明).
  • 在 ES2015 (ES6) 之前,仅在全局作用域或函数的顶层有效;ES2015+ 允许在控制流语句中使用它们,但规则很复杂.
  • 以后可以通过 square = ...(或以后的函数声明)覆盖.
  • 创建一个对象并将其分配给 square.prototype,即使我们不打算将它作为构造函数.
  • 尝试将其用作构造函数 (new square) 会起作用,但可能不会达到编码人员的预期:new 操作的结果将是一个对象使用 square.prototype 作为它的原型(并且 n * n 的函数返回值被丢弃).
  • 如果在全局范围内,则在全局对象上创建一个属性(因此是一个全局对象),因为它是一个函数声明.
  • 如果在函数中使用了 this,它将由函数的调用方式决定,因为它是一个正常"的代码.功能.
    • Hoisted (because it's a function declaration).
    • Until ES2015 (ES6), only valid at global scope or at the top-level of a function; ES2015+ allows them within control flow statements, but the rules are complex.
    • Can be overwritten later via square = ... (or a later function declaration).
    • Creates an object and assigns it to square.prototype, even though we don't intend it to be a constructor.
    • Attempts to use it as a constructor (new square) will work, but probably not do what the coder expected: The result of the new operation will be an object using square.prototype as its prototype (and the function's return value from n * n is thrown away).
    • If at global scope, creates a property on the global object (and thus, a global) because it's a function declaration.
    • If this were used within the function, it would be determined by how the function is called, as it's a "normal" function.
    • 选项 2:

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

      • 未提升(因为它是一个表达式),在控制流期间创建.
      • 在 ES2015 之前,由于它是一个匿名 函数表达式,因此该函数没有名称.在 ES2015+ 中,名称源自变量的名称​​(浏览器支持可能有点滞后,它在 ES2015 支持优先级列表中似乎较低).
      • 以后可以通过square = ...
      • 覆盖
      • 创建一个对象并将其分配给 square.prototype,即使我们不打算将它作为构造函数.
      • 尝试将其用作构造函数 (new square) 会起作用,但可能无法达到编码人员的预期(请参阅函数声明的注释).
      • 如果在全局范围内,则在全局对象(因此是全局对象)上创建一个属性,因为它是旧式 var 变量.
      • 如果在函数中使用了 this,它将由函数的调用方式决定,因为它是一个正常"的代码.功能.
        • Not hoisted (because it's an expression), created during control flow.
        • Until ES2015, since it's an anonymous function expression, the function didn't have a name. In ES2015+, the name is derived from the variable's name (browser support may lag a bit, it seems to be low on the ES2015 support priority list).
        • Can be overwritten later via square = ...
        • Creates an object and assigns it to square.prototype, even though we don't intend it to be a constructor.
        • Attempts to use it as a constructor (new square) will work, but probably not do what the coder expected (see note on the function declaration).
        • If at global scope, creates a property on the global object (and thus, a global) since it's an old-style var variable.
        • If this were used within the function, it would be determined by how the function is called, as it's a "normal" function.
        • 选项 2.5:(我添加了这个)

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

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

          Exactly like Option 2, except that on ES5 and earlier, the function has a true name (square). (Note that the name doesn't have to be the same as the name of the variable, although it is in this example.) (Bugs in IE8 and earlier would end up creating two functions instead of just one; details in this blog post by T.J. Crowder [principal author of this answer].)

          选项 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.但是现代 JavaScript 引擎已经优化了 arguments 的创建,如果您不使用它,并且设置 this 不太可能是一个巨大的成本.
          • 如果在全局范围内,则在全局对象(因此是全局对象)上创建一个属性,因为它是旧式 var 变量.
          • 因为它是一个箭头函数,如果在函数中使用this,它会使用与定义函数的代码相同的this,因为箭头函数关闭 this(而不是根据它们的调用方式设置它).
            • Not hoisted (because it's an expression), created during control flow.
            • The function's name is derived from the variable's name (browser support may lag a bit, it seems to be low on the ES2015 support priority list).
            • Can be overwritten later via square = ...
            • Doesn't create an object and assign it to square.prototype.
            • Attempts to use it as a constructor (new square) will fail with an informative error (TypeError: square is not a constructor).
            • Doesn't have arguments (but you can use rest arguments instead if you need arguments functionality).
            • Per spec, requires fewer things to be "set up" when calling it, as it doesn't have its own this and doesn't have arguments. But modern JavaScript engines already optimize-out the creation of arguments if you don't use it, and it's unlikely setting up this is a significant cost.
            • If at global scope, creates a property on the global object (and thus, a global) since it's an old-style var variable.
            • Because it's an arrow function, if this were used within the function, it would use the same this as the code where the function is defined, since arrow functions close over this (rather than having it set by how they're called).
            • 选项 4:

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

              也可以写成:

              const square = n => n * n;
              

              • 未提升,在控制流期间创建
              • 函数名源自变量名(浏览器支持可能有点滞后,它在 ES2015 支持优先级列表中似乎较低).
              • 不能以后通过square = ...
              • 覆盖
              • 不会创建对象并将其分配给square.prototype.
              • 尝试将其用作构造函数 (new square) 将失败并显示信息性错误(TypeError: square is not a constructor).
              • 没有参数(参见选项 3 的注释).
              • 根据规范,需要设置"的东西更少;调用它时(参见选项 3 的注释).
              • 如果在全局范围内,不会在全局对象上创建属性(但仍会创建全局对象),因为它是 ES2015+ const.
              • 因为它是一个箭头函数,如果在函数中使用this,它会使用与定义函数的代码相同的this,因为箭头函数关闭 this(而不是根据它们的调用方式设置它).
                • Not hoisted, created during control flow
                • The function's name is derived from the variable's name (browser support may lag a bit, it seems to be low on the ES2015 support priority list).
                • Can't be overwritten later via square = ...
                • Doesn't create an object and assign it to square.prototype.
                • Attempts to use it as a constructor (new square) will fail with an informative error (TypeError: square is not a constructor).
                • Doesn't have arguments (see notes on Option 3).
                • Per spec, requires fewer things to be "set up" when calling it (see notes on Option 3).
                • If at global scope, doesn't create a property on the global object (but still creates a global), since it's an ES2015+ const.
                • Because it's an arrow function, if this were used within the function, it would use the same this as the code where the function is defined, since arrow functions close over this (rather than having it set by how they're called).
                • 选项 5:(我添加了这个)

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

                  也可以写成:

                  let square = n => n * n;
                  

                  与选项 4 完全一样,只是以后可以通过 square = ...

                  Exactly like Option 4, except it can be overwritten later via square = ...

                  这篇关于在 ES6 中创建带箭头或不带箭头的顶级函数的优缺点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆