我对ES6和React都很陌生,但一直看到箭头函数。为什么有些箭头函数在瘦箭头后使用花括号,而有些则使用括号?例如:
const foo = (params) => (
<span>
<p>Content</p>
</span>
);
对比。
const handleBar = (e) => {
e.preventDefault();
dispatch('logout');
};
我对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
myFunc
中的someArray
之前缺少return
时。 - Rin and Len括号在箭头函数中用于返回一个对象。
() => ({ name: 'YourName' }) // This will return an object
这相当于
() => {
return { name : 'YourName' }
}
实际上,当有人在箭头函数声明中使用括号时,它等同于以下内容:
const arrow = number => number + 1;
|||
const arrow = (number) => number + 1;
|||
const arrow = (number) => ( number + 1 );
|||
const arrow = (number) => { return number + 1 };
=>
不带花括号表示return
,易于阅读,易于理解,包大小更小。看,它是纯粹的美。 - AmerllicAconst 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
const foo = (params) => (
<span>
<p>Content</p>
</span>
);
const foo = (params) => (<span><p>Content</p></span>);
JavaScript
将理解为语句:const foo = (params) => {} // this is not an object being returned, it's just an empty statement
const foo = (params) => {
let value = 1;
return value;
}
const foo = (params) => ({})
每个函数都有两个方面。
它们中的第一个是,每个函数(不仅仅是箭头函数)都有一个执行上下文(块作用域),在其中创建和使用变量。
换句话说,在函数的花括号 { ... } 内部声明和分配的内容会留在那里,并且对外部函数/变量不可见。
例如,当编写以下内容时:
let x = 100;
function doSomething() {
let x = 50;
console.log(x);
}
doSomething(); // 50
console.log(x); // 100
两个值都在控制台中显示(而不是“外部的x只是被内部函数的x替换”)。
尽管 let 通常不允许再次声明其他变量 x(具有相同名称 x),但在这种情况下,因为第二个 x 在 { ... } 中声明和初始化,它不会改变外部的 x,这也是因为在调用函数 doSomething 后,其中的x被创建、分配、打印到控制台,然后被销毁(从内存中删除)。所以每次我们通过运行 doSomething() 调用该函数时,这个过程都会发生。
因此,在理解函数时需要考虑的第一个方面就是:它们执行完后会忘记代码内部花括号中创建的变量值。
正因为如此,更容易理解它们的第二个方面——函数不能仅仅孤立地工作,它们还需要向其他函数发送数据,因此它们具有一些“报告方面”,用于外部化其花括号内计算结果的某些部分,这正是 return 语句存在的原因。
每个函数中都存在return,即使在console.log或alert()中,甚至在doSomething()中也是如此。但在这些情况下,我们没有明确地为其设置任何内容,它总是'return undefined'。 因此,写它并不是必要的,而是要知道在您没有返回特定内容的情况下,函数本身将通过返回undefined来为您完成。 当您编写(或使用)一个仅用于执行某些操作的函数时,它也将始终返回undefined。 您可以通过每个函数来检查该函数是否具有声明的返回值: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()),它们执行某些操作(将括号中的内容打印到警告框或控制台中),然后返回undefined。
现在回到箭头函数,它们不仅是编写函数的新符号表示法,还具有一些特定的功能。
首先,在箭头函数的括号中只有一个参数时,可以省略括号。
其次,如果花括号中只有一个语句,则也可以省略花括号。
第三个是,如果单个语句是一个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
如果箭头函数有两个或更多参数,我们不能省略它们周围的括号:
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
a+b;
你的代码将会表现为
return;
a+b;
所以最好写代码时加上括号,就像这样:
return (
a + b
);
正如MDN网站此处所解释的那样。
var func = x => x * x;
// concise body syntax, implied "return"
var func = (x, y) => { return x + y; };
// with block body, explicit "return" needed
另外请注意:
如果你在一个箭头函数中返回一个对象字面量作为结果,那么你必须将对象括在括号中,例如:myFunc = () => ({ data: "hello"})
。如果省略括号,你将会收到一个错误,因为构建工具会认为对象字面量的花括号是函数体的开始和结束。