1.作用域
全局作用域 函数作用域 块级作用域
var 定义的变量只有全局和函数作用域(ES5)没有块的概念,可以跨块访问,不能跨函数访问,在块级作用域内定义仍然是全局变量
let 定义的变量只能在块作用域里访问,不能跨函数访问
const 用来定义常量,使用时必须初始化,只能在块作用域里面访问
块级作用域:{}里面的都是如if(){},for(){},while(){} ,(function (){})()立即执行函数也是块级作用域
在上面的例子中,var定义的变量,for()相当于父级作用域,里面的{}子级作用域,当子作用域找不到变量定义会向上去父级作用域找,如果当前作用域定义了变量但未赋值,则会提示Undefined,不再去父级作用域中查找;如果在当前作用域使用之后定义了则会报is not defined的错,也不会再去父级查找。
2.变量声明
let var可以仅声明不赋值,const必须声明的时候就赋值
3.变量值是否可以修改
let var声明变量的值可以修改 const声明的变量如果是基本数据类型则不可修改,如果是引用类型则可以修改值,不可以修改地址
上面的例子中const 定义基本数据类型Number 修改其值后报错,接着我们看下面的例子:
在上面的例子中修改person对象的name属性并没有报错,而且修改成功了,这是怎么回事呢?
因为对象是引用类型的数据(地址保存在堆中,值保存在栈中),person中保存的仅是对象的指针,const仅能够保证指针不发生改变,修改对象的属性不会改变对象的指针,所以是被允许的。
我们来试着修改一下指针,让person指向一个新的对象,就会报错:
4. 是否可以在相同的作用域内重复声明
var 可以在同一作用域内重复声明,let const 不能在同一作用域内重复声明
5.变量提升(var有预解析,let没有)
var 声明的变量会进行变量提升,赋值不会提升,let声明的变量,const声明的常量不会提升。
var 定义变量时,JS在解析代码时会先把变量声明到作用域的对顶端,var有预解析,先使用后定义也不会报错只是读取不到后面的赋值。
上面的代码就相当于:
在函数作用域内部定义的变量,在内部执行代码时无法获取外部变量的值。
let定义的变量没有变量提升,先使用后定义会报错。let是先定义,然后再可以引用,否则程序会中断不会往下继续执行。
6.let 相较于var 的优势
优势体现在选项卡功能,应用多个按钮切换,for循环若换成var 则i 是全局变量循环结果为按钮的数量就无法实现