1、ES5中使用var来声明变量,会产生作用域提升的问题。例:
var a=1;
function scope(){
console.log(a);
var a=2;
}
scope(); //得到的结果既不是1也不是2,是undefined 因为JS引擎会把变量的声明提升到当前作用域的最前面。
2、ES5里面不存在块级作用域,只要是在作用域的范围内都能够被访问到。例:
var b=0;
for(;b<4;b++){
console.log(b); //得到的结果是0,而不是undefined。 如果存在块级作用域,那么返回的值就会是undefined。
var b=3;
}
3、ES6里面新增的let,let声明过的变量不能在相同作用域内进行重复声明。
function variable(){
let a=0;
var a=2;
}
variable(); //会报错,报'a' has already been declared的错, 由这一点可以说明let声明过的变量在同一作用域内不能再次声明。
4、let声明的变量只能在块级作用域内使用。
for(let i=0;i<3;i++){
console.log(i); //0,1,2
}
console.log( i ); //报错:i is not defined 说明let声明的变量只能在块级作用域内使用。
for(var i=0;i<3;i++){
console.log(i); //0,1,2
}
console.log(i); //3 而在ES5里面使用var声明的变量在全局作用域之内都可以使用。
5、let相当于严格模式的var,不再存在提升变量的声明问题。
console.log( a ); //undefined 变量提升了。
var a=2;
console.log(b); //b is not defined 不存在变量提升。
let b=2;
6、let声明的变量存在暂时性死区
var tmp = 123; //存在全局变量tmp,但在下面let又声明了一个局部变量tmp, if (true) { tmp = 'abc'; // 所以在这里绑定的块级作用域在let声明前,因此报错ReferenceError:tmp is not defined let tmp;
//ES6里面有明确的规定,如果区块中存在let、const命令,这些区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明前使用这些变量,都会报错。
(在let命令声明变量之前,该变量都是不可用的,这种现象用专业名词来描述是:暂时性死区) }
对于暂时性死区,typeof判断类型的不是一个百分之百的操作了。typeof x; //若是底下使用let声明了一下这个变量,则报错 x is not defined let x;
typeof aval; //undefined 这个变量根本没有被声明,则使用typeof反而不会报错。
function bar(x=y,y=2){ return [x,y]; } bar(); //报错 y is not defined 是由于x的默认值是y,而y还没有声明,属于“死区”,因此报错。
function bar(x=2,y=x){ return [x,y]; } bar(); //[2,2] //这样就不会报错了,因为x已经声明过了。
总结:ES6里面新增的let,let声明过的变量不能在相同作用域内进行重复声明,let声明的变量只能在块级作用域内使用,let相当于严格模式的var,不再存在提升变量的声明问题。let相对于var来说,有暂时性死区。
7、声明一个只读常量。一旦声明,常量的值就不能改变。
const PI=3.1415; PI PI=3; //报错 const声明的变量必须立即初始化,不能留到后面赋值。 const a; //报错 Missing initializer in const declaration 所以从这可以看出只声明不赋值,就会报错。
8、const的作用域与let相同,只在声明所在的块级作用域内有效。const命令声明的常量也不会提升作用域,同样存在暂时性死区,只能在声明的位置后使用。const声明的常量,也与let一样不可重复声明。
if(true){ const a=3; } a; //a is not defined 只在声明所在的块级作用域内有效。
9、const命令声明的常量也不会提升作用域。
if(true){ console.log( b ); //报错 b is not defined 声明的常量也不会提升作用域 const b=2; }
10、const声明的常量,也与let一样不可重复声明。
var name="simth"; let age=20; const name="Tom"; //报错 'name' has already been declared const age=28; //报错 age' has already been declared
总结:实际上const声明的变量名不指向数据,而是指向数据所在的地址。const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变。因此const是可以利用push给一个空的数组里面添加值。并且也能通过length得到它的长度。