use*_*530 0 javascript reactjs visual-studio-code
我在 ReactJS 应用程序中大量使用箭头函数样式(它们都使用带有钩子的函数样式)。
const handleKeyDown = (e) => {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
Visual Studio Code 一直在这里建议我使用一个命名函数,如:
function handleKeyDown(e) {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
这里的最佳做法是什么?我读过,箭头函数和命名函数在 javascript 中是等价的。这不是真的吗?在这里使用命名函数有什么好处吗?
有两个主要区别。
首先:
function handleKeyDown(e) {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
在这里,您使用的是函数声明(或函数语句);在箭头函数的情况下:
const handleKeyDown = (e) => {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
您正在使用函数表达式。事实上,它们被称为箭头函数表达式(因为没有“箭头函数声明”,它们的本质是一个表达式)。
所以更清楚地说,箭头函数版本更像是:
const handleKeyDown = function(e) {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
所以第一个区别是函数声明与函数表达式,(因此语句和表达式之间的区别:Javascript:语句和表达式之间的区别?)
对于与函数有关的内容,函数声明在函数表达式没有的地方被提升。这意味着这样的代码:
handleKeyDown({keyCode: 13});
function handleKeyDown(e) {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
完全有效(并且正在运行),其中的代码如下:
handleKeyDown({keyCode: 13});
const handleKeyDown = (e) => {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
将引发异常,因为handleKeyDown
尚未初始化。
函数表达式和函数声明之间的另一个区别是函数表达式是匿名的(未命名的)。这不再有效,因为 js 引擎现在能够确定与它们关联的名称:
const handleKeyDown = function(e) {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
但是,在这种情况下,箭头函数和函数表达式之间的区别在于您可以覆盖它:
const bar = function baz() {};
console.log(bar.name) // baz
Run Code Online (Sandbox Code Playgroud)
然而,重要的是要注意,名称baz
的作用域是函数的主体块。这意味着在外面不可用:
const bar = function baz() {
console.log("my name is:", baz.name)
}
console.log(bar.name) // "baz"
bar() // "my name is: baz"
baz() // ReferenceError: bar is not defined
Run Code Online (Sandbox Code Playgroud)
当您想要一个递归函数而不用它污染外部作用域时,这会很有用。常见的例子是setTimeout:
handleKeyDown({keyCode: 13});
function handleKeyDown(e) {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
handleKeyDown({keyCode: 13});
const handleKeyDown = (e) => {
doStuff(e.keyCode);
}
Run Code Online (Sandbox Code Playgroud)
也就是说,使用箭头函数表达式而不是函数(表达式或语句)的第二个主要区别是箭头函数本身的性质。MDN 有一个整洁的列表:
arguments
(object) 或 new.target 关键字。call
,apply
和bind
方法,一般依赖于建立范围。yield
,在其体内。为什么他们不适合的原因call
,apply
而且bind
是因为他们使用的封闭范围的上下文对象定义时; 基本上他们没有this
自己的。当您将它们用作事件处理程序时,这很明显:
const foo = () => {}
const bar = function() {}
console.log(foo.name) // "foo"
console.log(bar.name) // "bar"
Run Code Online (Sandbox Code Playgroud)
在哪里:
const bar = function baz() {};
console.log(bar.name) // baz
Run Code Online (Sandbox Code Playgroud)
总而言之,在定义可调用函数的每种方式之间肯定存在重叠区域的地方,每种方式都有自己的特征需要了解,以便正确使用它们,并避免可能出现的令人讨厌的错误。
归档时间: |
|
查看次数: |
387 次 |
最近记录: |