继续小实验,上次写到块级作用域,那么为什么需要块级作用域呢?书中给了两个场景:
1.没有块级作用域,内层变量可能会覆盖外层变量。举例:
var tmp = new Date() function f() { console.log(tmp) if(false) { var tmp = "hello world" } } f();//undefined
内层的tmp变量把外层的tmp变量覆盖,所以输出结果为undefined
2.用来计数的循环变量泄露为全局变量,举例:
var s = 'hello' for(var i = 0; i < s.length; i++) { console.log(s[i]) } console.log(i)//5
外层依然可以使用内层的i,所以仍然可以正常输出其值,感觉这两种情况很相似,都是因为没有块级作用域,内部的变量改变或者成为了外部变量。那么有了块级作用域后又怎样呢?举例:
function f() { let n = 5 if(true) { let n = 10 } console.log(n)//5 } f()
let声明的n只在他自己的块级作用域里面有效,出了作用域就无效,因此它没法改变外部的值。
const命令比较简单,它就是一个只读常量声明,一旦声明,常量的值就不能改变。并且必须立即初始化,不能留到以后赋值。
const PI = 3.1415 PI = 3 console.log(PI)//Uncaught TypeError: Assignment to constant variable.
有一点要注意的是const声明的常量在很多方面和let声明的变量相似,比如:只在声明所在的块级作用域内有效,const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。一样不可重复声明,所以在我看来const = let + 常量。
全局对象的属性,过去ES5里面全局对象的属性和全局变量等价:
var a = 1 console.log(window.a)//1
现在用let,const,class命令声明的全局变量不属于全局对象的属性了:
let a = 1 console.log(window.a)//undefined