无意中在变量声明之前调用了i18n这个变量,但这个变量是用let创建的,为什么依然是输出undefined而不是报错?

新手上路,请多包涵

validate.js

import Vue from 'vue'
import VeeValidate, { Validator } from 'vee-validate';
import zh_CN from 'vee-validate/dist/locale/zh_CN.js'
import VueI18n from 'vue-i18n';
Vue.use(VueI18n)

const config = {
    errorBagName: 'errorBags', // change if property conflicts.
    fieldsBagName: 'fieldBags',
    i18n:i18n,
    i18nRootKey: 'validation',
    dictionary: {
        zh_CN
    }
};

**console.log(i18n) //undefined
const i18n = new VueI18n({
    locale: 'zh_CN',
})**

Vue.use(VeeValidate, config);

Validator.extend("account", {
    getMessage: field => "必须是4到16位的数字字母下划线",
    validate: value => /^[a-zA-Z0-9_-]{4,16}$/.test(value)
});
Validator.extend("password", {
    getMessage: field => "必须是6到16位的数字字母",
    validate: value => /^[a-zA-Z0-9]{6,16}$/.test(value)
});

回复
阅读 2.6k
2 个回答

楼上的说的不大对。const并没有任何变量提升。照道理会产生暂时性死区 而报错。

clipboard.png

没有报错的原因是你上面的代码并不是直接执行,而是由构建工具来编译,其中语法的转译通常是交给babel
那么以babel为例

clipboard.png

此时代码被编译成了es5的语法 使用了var 此时才是作用域提升。

所以说答案 直接运行代码不是作用域提升,但是若有编译过程则编译后作用域提升

之前的回答不太对,确实对ES6的理论疏于研究了。。。
借此机会更新下知识,也把学到的东西和大家分享下。

准确的说,@阿蛇 的回答也不准确,const/let也会被提升,只是暂时不可访问。

具体来说,const/let虽然会被提升,但是在真正执行赋值(LexicalBinding)之前处于不能访问的状态,也就是说,在声明和赋值之间的时间段之内进行访问,都会抛出异常。

ECMAScript标准对此也有相应描述。
https://www.ecma-internationa...

The variables are created when their containing Lexical Environment is
instantiated but may not be accessed in any way until the variable's
LexicalBinding is evaluated.

以下之前的回答

这是因为i18n这个变量的声明被提升到了作用域的顶端。要注意的是,提升的仅仅是变量声明,并不包含赋值部分,所以在赋值语句执行之前,i18n都是undefined

更多的细节可以看我之前翻译的一篇文章

推荐问题
宣传栏