Javascript 变量是用let还是const声明的?
我使用ES6已经有一段时间了,我注意到当使用Javascript 变量是用let还是const声明的?,javascript,ecmascript-6,constants,let,hoisting,Javascript,Ecmascript 6,Constants,Let,Hoisting,我使用ES6已经有一段时间了,我注意到当使用var声明的变量按照预期被提升时 console.log(typeof name); // undefined var name = "John"; …使用声明的变量let或const似乎在提升方面存在一些问题: console.log(typeof name); // ReferenceError let name = "John"; 及 这是否意味着使用let或const声明的变量不被提升?这到底是怎么回事?在这个问题上,let和const之间
var
声明的变量按照预期被提升时
console.log(typeof name); // undefined
var name = "John";
…使用声明的变量let
或const
似乎在提升方面存在一些问题:
console.log(typeof name); // ReferenceError
let name = "John";
及
这是否意味着使用let
或const
声明的变量不被提升?这到底是怎么回事?在这个问题上,let
和const
之间有什么区别吗?引用ECMAScript 6(ECMAScript 2015)规范的第节
变量是在实例化其包含词法的环境时创建的,但在对变量的词法绑定进行求值之前,可能无法以任何方式访问
因此,为了回答您的问题,是的,让
和常量
提升,但在运行时评估实际声明之前,您无法访问它们。引用ECMAScript 6(ECMAScript 2015)规范,第节
变量是在实例化其包含词法的环境时创建的,但在对变量的词法绑定进行求值之前,可能无法以任何方式访问
因此,为了回答您的问题,是的,
让
和常量
提升,但在运行时评估实际声明之前,您无法访问它们。@thefourtheye正确地说,这些变量在声明之前无法访问。然而,它比这要复杂一点
使用let
或const
声明的变量是否未提升?这到底是怎么回事
所有声明(var
,let
,const
,函数
,函数*
,类
)在JavaScript中被“提升”。这意味着,如果在某个范围内声明了名称,则在该范围内,标识符将始终引用该特定变量:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
函数和块作用域1都是如此
var
/函数
/函数*
声明和let
/常量
/类
声明之间的区别在于初始化在作用域顶部创建绑定时,前者使用
未定义的或(生成器)函数进行初始化。但是,词汇声明的变量保持未初始化状态。这意味着当您尝试访问它时,会引发ReferenceError
异常。只有在对let
/const
/类
语句求值时,才会对其进行初始化,前面(上面)的所有内容都称为暂时死区
注意a让y
语句用未定义的初始化变量,如let y=undefined代码>会有
时间死区不是一个语法位置,而是变量(范围)创建和初始化之间的时间。在声明上方的代码中引用变量不是错误,只要该代码未执行(例如,函数体或简单的死代码),并且如果您在初始化之前访问变量,即使访问代码低于声明,也会引发异常(例如,在过早调用的已挂起功能声明中)
在这件事上,let
和const
之间有什么区别吗
不,就提升而言,它们的工作原理是相同的。它们之间唯一的区别是常量蚂蚁必须并且只能在声明的初始值设定部分分配(const one=1;
,两者都const one;
以及以后类似one=2
的重新分配无效)
1:var
声明仍然只在函数级别起作用,当然,@thefourtheye说这些变量在声明之前无法访问是正确的。但是,它比这要复杂一点
使用let
或const
声明的变量是否未被提升?这里到底发生了什么
所有声明(var
,let
,const
,function
,function*
,class
)都是在JavaScript中“提升”的。这意味着如果在某个范围内声明了名称,则标识符将始终在该范围内引用该特定变量:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
函数和块作用域1都是如此
var
/函数
/函数*
声明和let
/常量
/类
声明之间的区别在于初始化
前者用未定义的
或(生成器)初始化当绑定在作用域的顶部创建时,函数将正确运行。但是,词汇声明的变量保持未初始化状态。这意味着当您尝试访问它时,将抛出一个引用错误异常。只有当let
/const
/类语句被激活时,才会初始化它被称为暂时死区的一切
请注意,let y;
语句使用undefined
初始化变量,就像let y=undefined;
一样
时间死区不是一个语法位置,而是变量(作用域)创建和初始化之间的时间。在声明上方的代码中引用变量并不是一个错误,只要代码没有执行(例如,函数体或简单的死区代码),并且如果您在初始化之前访问变量,即使访问代码低于声明,它也会引发异常(例如,在一个被提升的游戏中)
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
function doSomething(arr){
//i is known here but undefined
//j is not known here
console.log(i);
console.log(j);
for(var i=0; i<arr.length; i++){
//i is known here
}
//i is known here
//j is not known here
console.log(i);
console.log(j);
for(let j=0; j<arr.length; j++){
//j is known here
}
//i is known here
//j is not known here
console.log(i);
console.log(j);
}
doSomething(["Thalaivar", "Vinoth", "Kabali", "Dinesh"]);
for(var i=1; i<6; i++){
setTimeout(function(){
console.log(i);
},1000)
}
for(let i=1; i<6; i++){
setTimeout(function(){
console.log(i);
},1000)
}
const foo = {};
foo.bar = 42;
console.log(foo.bar); //works
const name = []
name.push("Vinoth");
console.log(name); //works
const age = 100;
age = 20; //Throws Uncaught TypeError: Assignment to constant variable.
console.log(age);
console.log(x); // ReferenceError
let x = 3;
// this will work
u = 10;
var u;
// this will give an error
k = 10;
let k; // ReferenceError: Cannot access 'k' before initialization.
// this code works as variable j is declared before it is used.
function doSmth() {
j = 9;
}
let j;
doSmth();
console.log(j); // 9