【问题标题】:what is the difference between these two functions (arrow function vs function declaration) [duplicate]这两个函数有什么区别(箭头函数与函数声明)[重复]
【发布时间】:2020-06-11 20:24:21
【问题描述】:
function pickColor() {
    var random = Math.floor(Math.random() * colors.length);
    return colors[random];
}

let pickColor = () => {
    var random = Math.floor(Math.random() * colors.length);
    return colors[random];
}

当我尝试调用第二个时,我收到一条错误消息,提示“初始化前无法访问 'pickColor'”

【问题讨论】:

标签: javascript function ecmascript-6


【解决方案1】:

这是由于一种叫做“提升”的东西。

基本上当您使用function 时,JavaScript 会将函数移动到作用域的顶部,因此您可以在初始化之前访问它。使用 let 不会这样做。

func_1();

function func_1() {
    console.log("Thing");
}


func_2(); // will cause an error

let func_2 = () => console.log("Thing");

详细信息:一切都在技术上提升,但 letconst 在到达他们的线路之前不要初始化。如果您使用var,则变量将以undefined 开头

console.log(aa); //undefined
var aa = "hello";
console.log(aa); //hello

console.log(bb) // error
let bb = "hello";

旁注(这部分不是解决上述问题的方法): 1. 您应该使用const 而不是let,因为我认为您不需要更改函数的值。 2. 这些声明之间的另一个区别是关键字this 的值(在这种情况下相同,但可以不同)。我这里就不解释了,如果你做更多值得研究的Javascript,你可能会遇到它。

【讨论】:

  • 我尝试将箭头函数上的变量赋值更改为 const,但它仍然不起作用。
  • 抱歉,const 无法解决您的问题,问题是 usinf function 在声明之前使函数可用。如果要使用constlet,则需要在调用之前定义函数。我只是说const 在大多数情况下更适合函数
  • 谢谢!这只是意味着在文本编辑器中调用它之前编写函数吧?
  • @RyanHeaux 是的,就像声明变量时一样。
【解决方案2】:

let pickColor = ... 就像普通的变量声明 + 赋值一样。

分配= 仅在执行实际代码行时完成。

只有当调用发生在声明之后并且在可见范围内时,才能调用以这种方式定义的函数。

相反,function() 的定义是完全“提升”的,这意味着它们的行为就像是在 JS 块的顶部定义的一样,并且可以在它们的定义“之前”调用。

示例来自http://adripofjavascript.com/blog/drips/variable-and-function-hoisting.html

isItHoisted();

function isItHoisted() {
    console.log("Yes! This function declaration acts the same as if it was declared _before_ the call.");
}


isThisOtherOneHoisted(); // throws an ReferenceError if used before it is  assigned 

let isThisOtherOneHoisted = () => console.log("Javascript sees that the name exists, but the assignment has not been done.");

/**
like :

There is this variable isThisOtherOneHoisted defined later, just so you know.
isThisOtherOneHoisted(); // error, variable does not even containt a function yet
isThisOtherOneHoisted = () => console.log(...)

*/

作为附加细节,javascript 在初始化之前仍会“看到”它已被使用,这就是为什么错误消息与使用根本不存在的变量时不同的原因。

声明对于任何变量都会被提升,但只有变量存在的事实。带有=assignments 只在写入的地方执行。

【讨论】:

  • 每个声明都被提升。但是,对于letconst,变量未初始化,导致the temporal dead zone
  • @VLAZ 是的,感谢您指出这一点。我编辑了一点答案,试图让这一点更清楚。
【解决方案3】:

函数声明

function pickColor(){...}

与使用var 声明的任何变量一起移动到范围的顶部(首先被提升)。

只有在解释器遇到该行代码时才能访问使用let 声明的函数表达式。

示例 -

let two = () => {
  console.log('something else');
}

var x = 'demo'
let y = 'demo123'

function one() {
  console.log('something');  
};

function three(){
  one();  
}

变量xfunction one(){...}function three(){...}在执行开始后立即移动到作用域的顶部,

xundefined 直到该行 x = 'demo' 然后 x 被赋值为'demo'

变量y直到该行才被初始化或赋值

let y = 'demo123'

因为let是用来初始化变量的,所以let初始化的函数表达式也是如此。

【讨论】:

    猜你喜欢
    • 2021-02-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 2013-04-03
    相关资源
    最近更新 更多