前提概要
由于自身掌握基础知识不是很牢固,因此梳理一些ES的语法,便于自己学习。同时,也和大家一起分享,如有不对的或者不准确的地方,欢迎大家提出😄,我也积极修改。第一次正式发文章,如有不好的地方,还望担待。这就正式进入正题:
Let
ES6新增了let命令,用来声明变量。
1、let声明的全局变量不是全局对象window的属性
这就意味着,你不可以通过window.变量名的方式访问这些变量,而var声明的全局变量是window的属性,是可以通过window.变量名的方式访问的.
var a1 = 5
console.log(window.a1) // 5
let a2 = 6
console.log(window.a2) // undefined
2、用let定义变量不允许重复声明
使用var可以重复定义,使用let却不可以。
var a1 = 5
var a1 = 6
console.log(a1) // 6
let a2 = 5
let a2 = 6
// 语法错误
// Uncaught SyntaxError: Identifier 'a2' has already been declared
3、let声明的变量不存在变量提升
function foo() {
console.log(a)
var a = 5
}
foo() //undefined
上述代码中,a的调用在声明之前,所以它的值是undefined,而不是Uncaught ReferenceError(引用错误)。实际上因为var会导致变量提升,上述代码和下面的代码等同:
function foo() {
var a
console.log(a)
a = 5
}
foo() //undefined
而对于let而言,变量的调用是不能先于声明的,代码如下:
function foo() {
console.log(a)
let a = 5
}
foo()
// Uncaught ReferenceError: Cannot access 'a' before initialization
在代码中:a的调用是在声明之前,因为let没有发生变量提升,所有读取a的时候,并没有找到,而在调用之后才找到 let 对a的定义,所以会报错
4、let声明的变量具有暂时性死区
只要块级作用域内存在let命令,这个区块对命令声明的变量,从一开始就形成了封闭作用域,它所声明的变量就绑定在了这个区域,不再受外部的影响。
var a = 5
if(true){
a = 6
let a
}
// Uncaught ReferenceError: Cannot access 'a' before initialization
上面代码中,存在全局变量a ,但是块级作用域内let又声明了一个局部变量a,导致后者绑定这个块级作用域,所以在let声明变量前,对a赋值会报错。
因此,在代码块内使用let声明变量之前,该变量都是不可用的,在语法上称之为‘暂时性死区’
5、let声明的变量拥有块级作用域
{
let a = 5
}
console.log(a) // undefined
a变量是在代码块{}中使用let定义的,它的作用域是这个代码块内部,外部无法访问。
总结
使用let声明的变量:
- 不属于顶层对象window
- 不允许重复声明
- 不存在变量提升
- 暂时性死区
- 块级作用域
Const
const除了具有let的块级作用域和不会变量提升外,还有就是它定义的是常量,在用const定义变量后,我们就不能修改它,对变量的修改会抛出异常。
ES5中可以使用Object.defineProperty()来实现定义常量::
Object.defineProperty(window, 'PI', {
value: 3.14,
writable: false,
})
console.log(PI) // 3.14
PI = 5
console.log(PI) // 3.14
1、用const定义的变量不允许被修改的
const PI = 3.14
console.log(PI) // 3.14
PI = 5
console.log(PI)
// Uncaught TypeError: Assignment to constant variable.
这个代码块中因为对PI尝试修改,导致浏览器报错,这就说明const定义的变量是不能被修改的,它是只读的。
const PI
PI = 3.14
// Uncaught SyntaxError: Missing initializer in const declaration
注意: const 声明的变量必须进行初始化,不然会抛出异常 Uncaught SyntaxError: Missing initializer in const declaration。
2、重点来咯
const obj = {
name: '谢永强',
age: 34
}
obj.address = '象牙山'
console.log(obj)
// {name: "谢永强", age: 34, address: "象牙山"}
小伙伴们会注意到const定义的obj发生了改变...
这时我们就应该了解JS变量是如何存储的,描述如下:
基本数据类型是存在栈内存(stack)当中。引用数据类型(复杂数据类型)存在于堆内存(heap)当中,在栈内存当中存在一个引用地址,这个引用地址会指向堆内存的地址。
上述代码可知:
const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
总结
使用const声明的常量:
- 不属于顶层对象window
- 不允许重复声明
- 不存在变量提升
- 暂时性死区
- 块级作用域