没有花括号的箭头函数

Arrow function without curly braces

我是 ES6 和 React 的新手,我一直看到箭头函数。为什么有的箭头函数在粗箭头后面用花括号,有的用圆括号? 例如:

const foo = (params) => (
    <span>
        <p>Content</p>
    </span>
);

对比

const handleBar = (e) => {
    e.preventDefault();
    dispatch('logout');
};

圆括号是返回一个值,大括号是执行多行代码。

您的示例看起来令人困惑,因为它使用的 JSX 看起来像多个“行”,但实际上只是被编译为一个“元素”。

这里有一些更多的例子,它们都做同样的事情:

const a = (who) => "hello " + who + "!";
const b = (who) => ("hello " + who + "!");
const c = (who) => (
  "hello " + who + "!"
);
const d = (who) => (
  "hello "
    + who
    + "!"
);
const e = (who) => {
  return "hello " + who + "!";
}; 

您还会经常在对象字面量周围看到括号,因为这是一种避免解析器将其视为代码块的方法:

const x = () => {} // Does nothing
const y = () => ({}) // returns an object

也可以使用花括号来防止单线箭头函数返回值——或者让下一个开发人员明白单线箭头函数不应该返回任何东西,在这种情况下.

例如:

const myFunc = (stuff) => { someArray.push(stuff) }
const otherFunc = (stuff) => someArray.push(stuff)

console.log(myFunc())    // --> logs undefined
console.log(otherFunc()) // --> logs result of push which is new array length

在您的第一个示例中,箭头函数的右侧显示了一个由分组运算符括起来的表达式:

const foo = (params) => (
  <span>
    <p>Content</p>
  </span>
);

类似的可比案例如下:

const foo = (params) => (<span><p>Content</p></span>);

在上述使用单个表达式的情况下,一个区别是右侧是函数 的returned 值。

另一方面,如果您使用大括号,JavaScript 将理解为语句:

const foo = (params) => {} // this is not an object being returned, it's just an empty statement 

因此,using 语句是一个良好的开端,它可以让您在其中包含多行代码,如果该函数旨在 return 值,则需要使用 "return":

const foo = (params) => {
    let value = 1; 
    return value;
}

如果您想 return 最短形式的空对象:

const foo = (params) => ({}) 

See tests

其实在公文包里,有人在箭头函数声明中使用大括号,等于如下:

const arrow = number => number + 1;

|||

const arrow = (number) => number + 1;

|||    

const arrow = (number) => ( number + 1 );

|||

const arrow = (number) => { return number + 1 };

括号用于 return 对象的箭头函数。

() => ({ name: 'YourName' })  // This will return an object

相当于

() => {
   return { name : 'YourName' }
}

重复回答post(),仅供参考:

  var func = x => x * x;                  
    // concise body syntax, implied "return"

    var func = (x, y) => { return x + y; }; 
    // with block body, explicit "return" needed

供参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Function_body

另请注意: 如果你要返回一个对象字面量作为粗箭头函数的结果,那么你必须将对象括在括号中,例如 myFunc = () => ({ data: "hello"})。如果省略括号,您将收到错误消息,因为构建工具会假定对象文字的大括号是函数体的开始和结束。

圆括号有一个隐式的 return 语句,而花括号则需要一个显式的 return 语句

如果你在箭头后面使用大括号来定义函数体,你必须使用'return'关键字来return一些东西。

例如:

const myFun1 = (x) => {
    return x;
}; // It will return x

const myFun2 = (x) => {
    x;
}; // It will return nothing

如果使用括号,则无需提及'return'关键字。

例如:

const myFunc1 = (x) => x; // It will return x

const myFunc2 = (x) => (x); // It will also return x

每个函数都有两个方面。

首先是每个函数,不仅仅是箭头函数,都有一个执行上下文(块作用域),变量在其中创建和使用。

换句话说,在函数的大括号 { ... } 内,在那里声明和分配的内容将保留在那里,并且对外部函数/或变量不可见。

例如,写成

let x = 100;

function doSomething() {
  let x = 50;
  console.log(x);
}

doSomething();     // 50
console.log(x);    // 100

两个值都显示在控制台中(而不是 'x from outside just being replaced by x from inside the function')。

你看到尽管 let 通常不允许再次声明其他变量 x(具有相同的名称 x), 在这种情况下,因为第二个 x 是在 { ... } 内部声明和初始化的,所以它不会改变外部 x,这也会发生因为在调用函数 doSomething 之后,它内部的 x 被创建、分配、打印在控制台中,然后被销毁(从内存中删除)。因此,每次我们通过 运行 doSomething() 调用该函数时都会发生该过程。

所以这是理解函数时要考虑的第一个方面:它们执行然后忘记了花括号内代码创建的值。

正因为如此,更容易理解它们的第二个方面——因为函数不能独立于其他函数工作,它们还需要向其他函数发送数据,所以它们有一些 'reporting aspect' 用于外部化部分结果在花括号内计算,这正是 return 语句存在的原因。

Return存在于每个函数中,甚至在console.log或alert()中,甚至在doSomething(),但在这些我们没有明确设置的情况下,它总是'return undefined' .

因此没有必要编写它,但要知道如果您没有 return 特定的东西,函数本身会通过 return 未定义来为您完成。

当您编写(或使用)一个仅用于执行某些操作的函数时,它也将 return 未定义。总是。

你可以用(显然)没有声明的每个函数检查那个东西 return:

let x = alert(100);
console.log(x); // undefined

let y = doSomething(); // console prints 50
console.log(y);        // 50, then undefined --- 2 lines

console.log(alert('Hello')); // undefined

console.log(console.log('Okay')); // Okay , then undefined

这是为什么?

因为 alert() 是全局对象 window 的一个方法(在浏览器中)(所以它实际上是 window.alert() )还有 console.log() (这是window.console.log() 也一样),执行某些操作( 在警告框或控制台中打印 () 和之间的任何内容然后 return 未定义).

现在,回到箭头函数,它们不仅是编写函数的一些新的表示法,而且还具有一些特定的功能。

首先,如果你在箭头函数中只有一个参数在()之间,你可以不写括号。

其次,如果大括号内只有一个语句,则大括号也可以省略。

第三个,如果单条语句是return语句,可以省略return.

这个词

不知何故,如果需要,我们可以使用这些将许多常用函数转换为箭头函数:

function doSomething() {let x = 50; console.log(x);} // as function declaration

let doSomething = function() {let x = 50; console.log(x);}; // as function expression, which is an anonymous function assigned to the variable 'doSomething'

let doSomething = () => {let x = 50; console.log(x);}; // as arrow function

// let's transform it further

let doSomething = () => {console.log(50)}; //

// that is equivalent to ---- let doSomething = () => {console.log(50); return undefined};
// or even to           ---- let doSomething = () => {return ( console.log(50) ) };
// because anyways, *console.log* has *return undefined* in it, as explained above

//which is the same as  ---- let doSomething = () => {return console.log(50) };

// let's now apply the rules 2 and 3 from above, one by one:

let doSomething = () => return console.log(50);

let doSomething = () => console.log(50);

// Obviously, this just shows how we could rewrite many usual functions (functions declarations) into arrow functions
// we can do that safely if we don't have any **this** involved in the functions, of course
// also, from all lines of code above only one must remain, for example the last one.

// the last one, despite only having ---- console.log(50) --- as the execution aspect, it also ---- returns undefined ---- as well

// obviously ---- console.log( typeof doSomething );   // function
// while     ---- console.log( typeof doSomething() ); // undefined

如果箭头函数有 2 个或更多参数,我们不能省略它们周围的括号:

function sum(a, b) {let total = a + b; return total}

let sum = function(a, b) {let total = a + b; return total};
// or
let sum = (a, b) => {let total = a + b; return total};
// or
let sum = (a, b) => {return a + b};
// or
let sum = (a, b) => a + b;

对于如上的简单操作,粗箭头符号'=>'可以被“读取”为转化为,在换句话说,a和b 被(被)转化为 a + b.

与此相反,还有一些函数可以验证一些数据(例如检查数据类型等),比如这个

let isNumber = x => typeof x === "number";
// or
let isNumber = (x) => {return (typeof x === "number")};
// obviously, 
isNumber("Hello, John!"); // false

那些不转换数据,因此箭头符号可以读作 ,条件是 ,或者相似。

换句话说,像

这样的函数
let double = x => x * 2    // 'double' is a function that transforms x into x*2

与检查函数不同(主要用于过滤器、排序和其他类型的验证函数,通常作为回调函数等)

let isArray = arr => Array.isArray(arr) // that last one already returns boolean by itself, no need to write return (Array.isArray() etc)

关于 return 的最后一件事是,当您在多行中编写代码时,ASI(自动分号插入)将插入一个';'在 return 之后,如果你在输入 return 之后错误地按回车键,这将破坏代码,因此而不是

return
a+b;

您的代码将表现为

return;
a+b;

所以你最好像这样写带括号的代码:

return (
  a + b
);

也如 MDN 网站 here 中所述。