【问题标题】:JavaScript arrow function assignmentJavaScript 箭头函数赋值
【发布时间】:2019-10-21 11:11:58
【问题描述】:

我尝试用谷歌搜索,但我无法与谷歌讨论,有时在课程中我看到讲师将箭头函数分配给这样的变量。

const s = ( ) => { }

在什么情况下我需要该语法而不使用

   function s( ) { }

我的基本问题 --> 何时使用

const s = ( ) => { } 

对比

function s( ) => { }

.. 为什么要赋值 ...这是我的主要问题(我何时以及为什么赋值?)为什么不使用箭头函数而不将其分配给变量? ?

【问题讨论】:

  • “在什么情况下我需要该语法而不使用” s()调用该函数。为此,必须首先将功能分配给s。这就是第一个示例正在做的事情。他们互相恭维。
  • 第一行声明一个函数,第二行 - 调用它。
  • 为什么赋值调用函数!?? @Zerkms
  • @HosMercury 它没有
  • 刚刚在 s( ) { }之前添加了函数

标签: javascript arrow-functions


【解决方案1】:

您的示例展示了两种声明函数的方法。

这是function declaration 的示例。

function s() {
// some code
}

这是定义函数的另一种方式,称为function expression

const s = function() {
// some code
}

这是arrow function。除了 thisarrow function 和其他两个之间的处理方式之外,它们几乎是编写相同函数的 3 种方式。

const s = () => {
// some code
}

如以下回复所述,function declaration and function expressionES5 功能,arrow functionES6 功能。

【讨论】:

  • 什么情况下代码在我将函数类型更改为表达式函数之前不起作用!?? .. 就像事件一样,它必须是表达才能起作用.. 我的问题基本上是使用一个或另一个的角色?
  • 对于function declaration,您应该阅读hoisting。这允许在声明函数之前或之后调用声明的函数。它在全球范围内可用。如果您不希望这种情况发生,您仍然可以function expressionarrow functions
  • @HosMercury 不用担心。 So why with Callbacks i have to use arrow。能给我举个例子吗?你不必使用arrow functions 来使用回调
  • 这有点难以直接回答,因为您会发现,您决定做某事的很多原因取决于需要什么以及在什么上下文中使用它。就像我上面说的,在考虑this 时,您会决定是否使用function declaration 而不是arrow function
  • 在 React 中,看看这个问题,stackoverflow.com/questions/48699573/…
【解决方案2】:

你的例子做了不同的事情:第一个声明一个函数s,第二个调用s()

为了清楚起见...

// ES5
var multiplyES5 = function(x, y) {
  return x * y;
};

// ES6
const multiplyES6 = (x, y) => { 
  return x * y;
};

【讨论】:

  • const真的有必要吗?没有它我试过了,没有区别:函数multiplyES6工作相同。
【解决方案3】:

箭头函数在哪里改进你的代码(你应该在哪里使用它们) -

传统 lambda 函数以及现在 JavaScript 中的箭头函数的主要用例之一是用于一遍又一遍地应用于列表中的项目的函数。

例如,如果您想要使用映射转换一组值,那么箭头函数是理想的:

const words = ['hello', 'WORLD', 'Whatever'];
const downcasedWords = words.map(word => word.toLowerCase());

一个非常常见的例子是提取对象的特定值:

const names = objects.map(object => object.name);

类似地,当使用 forEach 将旧式 for 循环替换为现代迭代器式循环时,箭头函数可防止 this父母让他们非常直观。

this.examples.forEach(example => {
   this.runExample(example);
});

Promise 和 Promise Chains - 箭头函数使代码更简洁、更直观的另一个地方是管理异步代码。

Promises 使管理异步代码变得更加容易(即使您对使用 async/await 感到兴奋,您仍然应该了解基于 async/await 构建的 Promise!)

然而,在使用 Promise 时,仍然需要定义在异步代码或调用完成后运行的函数。

这是放置箭头函数的理想位置,尤其是当您的结果函数是有状态的、引用对象中的某些内容时。示例:

this.doSomethingAsync().then((result) => {
  this.storeResult(result);
});

对象转换 - 箭头函数的另一个常见且极其强大的用途是封装对象转换。

例如,在 Vue.js 中,有一种常见的模式是使用 mapState 将 Vuex 存储的片段直接包含到 Vue 组件中。

这涉及定义一组“映射器”,这些映射器将从原始完整状态对象转换为准确提取相关组件所需的内容。

这些简单的转换是使用箭头函数的理想而美丽的地方。示例:

export default {
  computed: {
     ...mapState({
      results: state => state.results,
      users: state => state.users,
     });
  }
}

不应该使用箭头函数的地方 -

在许多情况下箭头函数不是一个好主意。它们不仅会帮助您,还会给您带来麻烦。

第一个是对象的方法。这是一个示例,其中函数上下文和 this 正是您想要的。

有一段时间的趋势是使用类属性语法和箭头函数的组合来创建“自动绑定”方法,例如事件处理程序可以使用但仍绑定到类的方法。

这看起来像:

class Counter {
counter = 0;

  handleClick = () => {
    this.counter++;
  }
}

这样,即使handleClick 由事件处理程序调用而不是在Counter 实例的上下文中调用,它仍然可以访问实例的数据。

这种方法的缺点是多方面的,

虽然使用这种方法确实为您提供了一种符合人体工程学的快捷方式来拥有一个绑定函数,但该函数的行为方式有很多不直观,如果您尝试将此对象作为子类/将此对象用作原型。

改为使用常规函数,并在必要时将其绑定到构造函数中的实例:

class Counter {
  counter = 0;

  handleClick() {
    this.counter++;
  }

  constructor() {
    this.handleClick = this.handleClick.bind(this);
  }
}

深度调用链 - 箭头函数可能给您带来麻烦的另一个地方是当它们将被用于许多不同的组合时,尤其是在函数调用的深层链中。

核心原因与匿名函数相同——它们给出了非常糟糕的堆栈跟踪。

如果你的函数只向下一层,比如在迭代器内部,这还不错,但是如果你将所有函数定义为箭头函数并在它们之间来回调用,你会很漂亮当您遇到错误时卡住并收到如下错误消息:

{anonymous}()
{anonymous}()
{anonymous}()
{anonymous}()
{anonymous}()

具有动态上下文的函数 - 箭头函数可能给您带来麻烦的最后一种情况是在 this 动态绑定的地方。

如果您在这些位置使用箭头函数,则该动态绑定将不起作用,您(或稍后使用您的代码的其他人)可能会对为什么事情没有按预期工作感到非常困惑。

这方面的一些关键示例:

  • 调用事件处理程序时将 this 设置为事件的 currentTarget 属性。
  • 如果您仍在使用 jQuery,大多数 jQuery 方法会将 this 设置为已选择的 dom 元素。
  • 如果您使用的是 Vue.js,方法和计算函数通常会将 this 设置为 Vue 组件。

当然,您可以故意使用箭头函数来覆盖此行为,但尤其是在 jQuery 和 Vue 的情况下,这通常会干扰正常功能,并让您感到困惑,为什么看起来与附近其他代码相同的代码不起作用。

这段摘自here

【讨论】:

    【解决方案4】:

    我假设您在更新中是指function s( ) { }

    注意该函数声明如何包含名称s。这隐式创建了一个变量s 并将函数分配给它。箭头函数定义不包含名称。所以在其他使用/调用/引用函数其他地方你必须将它分配给一个变量显式

    为什么不使用箭头函数而不将其分配给变量??

    这样做的唯一原因是将调用括号放在定义之后,例如

    (() => console.log('test'))()

    这将立即定义并调用该函数,将“test”打印到控制台。

    但是这样做没有多大意义,因为代码相当于只是写

    console.log('test')
    

    【讨论】:

      【解决方案5】:

      所以在 JavaScript 中我们一直在编写函数表达式,以至于我们决定应该使用更紧凑的语法来定义它们。这是编写函数的另一种方式。

      const square = x => {
        return x * x;
      }
      

      我故意在 x 周围没有括号,因为当只有一个参数时,当前语法说我们可以取消括号。

      上面其实是全功能的,你可以在上面运行square(4);得到16

      想象一下你有这样写的嵌套回调:

      const square = function(x){
        return x * x;
      }
      

      看到关键字function 到处都是,可能会在一段时间后让你发疯。

      箭头函数更简洁,更精简,但箭头函数不仅仅是语法糖,还有另一个区别,那就是关键字this

      如果您对关键字this 没有广泛的了解,我强烈建议您开始从那里获取有关该主题的一些可靠信息,至少与箭头函数有关。该研究应该会发现在哪些情况下您需要使用箭头函数。

      至于为什么要给它分配一个变量,你必须看看 mph85 概述的箭头函数的演变。你从函数声明开始:

      function isEven(num) {
        return num % 2 === 0;
      }
      

      分配给一个匿名函数声明,作为一个名为isEven的变量:

      const isEven = function(num) {
        return num % 2 === 0;
      }
      

      分配给名为isEven的变量的匿名函数声明演变为分配给所述变量的箭头函数表达式。

      const isEven = (num) => {
        return num % 2 === 0;
      }
      

      我们可以提高赌注并通过隐式返回使其更简洁,我们可以删除括号、花括号和return 关键字,如下所示:

      const isEven = num => num % 2 === 0;
      

      我认为观察它是如何演变的很重要,所以当你看到上面的最后一个版本时,它不会让你失望。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-30
        • 2018-07-02
        • 2018-01-08
        • 2019-06-16
        • 1970-01-01
        • 2019-01-06
        • 2017-04-18
        • 2022-01-21
        相关资源
        最近更新 更多