在ES5中,var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,ES6中,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
当然,在ES6中也不是没有变量提升,当你在最外层定义let时,之后也是可以变量提升的
即使在写变量名时,ES5和ES6都是不允许重复声明的,否则会报错
image.png也不能函数内部重新声明参数
image.png为什么要有块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
第一种场景,内层变量可能会覆盖外层变量。
第二种场景,用来计数的循环变量泄露为全局变量。
ES6中的作用域不会相互影响,即使在全局和局部的变量名声明的一样,当打印全局的值时,也不会影响局部的值
而且ES6 允许块级作用域的任意嵌套。外层的变量名可以和内层的变量名一样,但是外层的访问不到内层的变量
块级作用域与函数声明
函数能不能在块级作用域之中声明?这是一个相当令人混淆的问题。
ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
允许在块级作用域内声明函数。
函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
同时,函数声明还会提升到所在的块级作用域的头部。
注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。
根据这三条规则,在浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于var声明的变量。
另外,还有一个需要注意的地方。ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。
现在有种办法可以将块级作用域变成表达式,也就是说可以有返回值,只要在块级作用域之前加do,让他变成do表达式
const
const是一个只读的常量,一旦定义,就不能更改,否则会报错。
也就意味着,一旦声明就必须立即初始化,不能留到之后再赋值。
当然了,不声明变量,也会报错。
并且,const的作用域和let的命令相同:必须在声明的作用域之内才会有效。
const也同let一样,不会变量提升,存在暂时性死区,也不可重复声明。
const不是说它定义的那个值不得改动,而是它指向内存的地址不得改动
对于简单的数据类型(数值,字符串,布尔值)的时候,他们的值就存放在变量指向的内存地址中。也因此等同于常量
然而,对于复合数据类型(对象,数组),变量指向内存时就一个指针,而const只能保证这个指针是固定的,对于其中指向的数据结构是不是可变的就完全不能控制了,你也可以在数据中添加或者删除数据
如果说,你要讲数据什么的都固定好,不让别人在里面进行添加键值对,也
网友评论