var
var 声明的变量 存在 变量提升 即 在声明该变量之前就可以使用,值为 undefined ,其作用域为全局;
let 和 const
let 用法类似于 var ,但是所声明的变量,只在 let 命令所在的代码块内有效;
const 只能用来声明常量,一旦赋值,不能修改,故使用 const 不能只声明不赋值;
区别
var 和 let 的区别
使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升,且相同作用域内不可以重复声明同一个变量;
let 和 const 的区别
let 声明的变量可以重新赋值,而 const 声明的是一个常量,一旦赋值就不可再变,所以声明时就要赋值;
var 存在变量提升,let 和 const 不存在;
var 可以重复声明,let 和 const 不可以;
var 声明的变量可以在函数内部全局使用;
let 和 const 有块作用域,只在语句所在的代码块起作用;
const 声明的是常量,不可以重新赋值;
暂时性死区
ES6 明确规定,如果区块中存在 let 和 const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用 let 命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
问题:
- const 声明一个对象,还可以新增对象的属性或修改对象中属性的值吗?
答:可以,引用类型的数据实际存储的是一个引用地址,这个地址指向一个对象。不可变的只是这个地址,即不能把已声明的常量指向另一个地址,而对象本身是可变的,新增/修改属性都不会引起地址值的变化,故不会报错;
本质:const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const 只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。
拓展:已定义的对象不希望被修改,该如何做?1. // 使用 Object.freeze 方法冻结对象,冻结后的对象不可添加新属性(常规模式下无效,严格模式下报错) 2. const obj = { name: 'xiaolonga', age: 18, } Object.freeze(obj); console.log(obj, 'obj'); obj.age = 19; // 报错 console.log(obj, '修改属性'); obj.career = 'web前端工程师'; // 报错 console.log(obj, '添加属性');