JavaScript:let和const的吊装差异? 背景

JavaScript:let和const的吊装差异? 背景,javascript,node.js,ecmascript-6,Javascript,Node.js,Ecmascript 6,我有一个函数,负责生成一个随机数并使其可用 "use strict"; module.exports = function(args) { let { min, max, } = args; let currNumber = genRandom(min, max); const genRandom = (min, max) => Math.floor(Math.random() * max) + min; co

我有一个函数,负责生成一个随机数并使其可用

"use strict";

module.exports = function(args) {
    let {
        min,
        max,
    } = args;

    let currNumber = genRandom(min, max);

    const genRandom = (min, max) => Math.floor(Math.random() * max) + min;

    const getNumber = () => currNumber;    

    return Object.freeze({
        getNumber
    });
};
问题 出于我不理解的原因,当我使用Node.js 7.8运行此代码时,我得到一个错误,即未定义
genRandom

但如果我将代码更改为:

let currNumber = genRandom(min, max);

const genRandom = (min, max) => Math.floor(Math.random() * max) + min;
致:

那就行了

我不明白为什么会这样。我以为
const
let
就像
var
一样被吊起来,但这让我相信我错了

问题:
有人能给我解释一下这种行为吗?

var
不同的是,变量在声明之前是不可访问的

只需检查规格:

变量是在实例化其包含词法的环境时创建的,但在对变量的词法绑定进行求值之前,可能无法以任何方式访问

语法

词汇折旧[在,收益率]:
LetOrConst绑定列表[?In,?Yield]

LetOrConst:

常数

BindingList[In,Yield]:
词汇结合[?In,?屈服]
绑定列表[?In,?Yield],词典绑定[?In,?Yield]

词库绑定[In,Yield]:
BindingIdentifier[?Yield]初始值设定项[?In,?Yield]opt
BindingPattern[?屈服]初始值设定项[?In,?屈服]

我以为const和let就像var一样被提升,但这让我相信我错了

不太可能,
let
const
确实被提升了,或者我喜欢称之为半提升。
var foo
let foo
之间有两大区别:作用域和初始化。您已经知道范围差异。第二个是使用
var foo
foo
的声明和初始化(使用
undefined
)都被提升。使用
let
,仅提升
foo
的声明,而不提升初始化
foo
仅在逐步执行代码到达
let foo
语句时初始化。不能使用(读取或写入)未初始化的标识符。不能使用标识符的这段时间称为时间死区(TDZ)

即使使用
var
,挂起的初始化也是
未定义的初始化,而不是
=
右侧的值:

console.log(foo的类型);//“未定义”
foo();//TypeError:foo不是一个函数

var foo=()=>{}
var
不同的是
const
let
变量在声明之前是不可访问的。因此,它们不会被提升到函数的顶部,对吗?@tsh您可能希望将其作为答案发布。仅供参考,使用
var
也会导致问题。变量可能存在,因为它的定义已被提升,但它没有值,直到为它指定值的代码行在放置它的位置运行。现在,如果您使用
函数genRandom(){}
来定义本地函数,那么整个函数定义将被提升。因此,这与
let
const
或ES6无关。任何类型变量的赋值都不会被提升。@jfriend00:这会导致问题,但会导致另一个问题。:-)写得很好。谢谢你的解释
const genRandom = (min, max) => Math.floor(Math.random() * max) + min;

let currNumber = genRandom(min, max);