JavaScript基础
wen 2021/5/20 JavaScript
# 1. 数据类型
JavaScript 中基本数据类型和引用数据类型是如何存储的
在刚开始学习程序设计的时候没有在意内存这些基础知识,导致后来在提到“什么什么是存在栈中的,栈中只是存了一个引用”这样的话时总是一脸懵逼。后来渐渐的了解了一些内存的知识,这部分还是非常有必要了解的。
# 基本数据结构
- 栈:只允许在一段进行插入或者删除操作的线性表,是一种先进后出的数据结构。
- 堆:是基于散列算法的数据结构。
- 队列:是一种先进先出(FIFO)的数据结构。
# JavaScript 中数据类型的存储
JavaScript 中将数据类型分为基本数据类型和引用数据类型,它们其中有一个区别就是存储的位置不同。
# 基本数据类型
我们都知道 JavaScript 中的基本数据类型有:
- String
- Number
- Boolean
- Undefined
- Null
- Symbol(暂时不管)
基本数据类型都是一些简单的数据段,它们是存储在栈内存中。
# 引用数据类型
JavaScript 中的引用数据类型有:
- Array
- object
引用数据类型是保存在堆内存中的,然后再栈内存中保存一个对堆内存中实际对象的引用。所以,JavaScript中对引用数据类型的操作都是操作对象的引用而不是实际的对象。
可以理解为,栈内存中保存了一个地址,这个地址和堆内存中的实际值是相关的。
# 复制
基本数据类型:对于基本数据类型,如果进行复制,系统会自动为新的变量在栈内存中分配一个新值,很容易理解。
引用数据类型:如果对于数组、对象这样的引用数据类型而言,复制的时候就会有所区别了。系统也会自动为新的变量在栈内存中分配一个值,但这个值仅仅是一个地址。也就是说,复制出来的变量和原有的变量具有相同的地址值,指向堆内存中的同一个对象。
# 为什么?
为什么基本数据类型存在栈中,而引用数据类型存在堆中呢?
- 堆比栈大,栈比对速度快。
- 基本数据类型比较稳定,而且相对来说占用的内存小。
- 引用数据类型大小是动态的,而且是无限的。
- 堆内存是无序存储,可以根据引用直接获取。
# 2. ES6变量命名方式以及块级作用域
# var 声明及变量提升机制
- 在ES6之前,在函数作用域中或者全局作用域中通过
var
关键字来声明变量,无论是在代码的哪个位置,这条声明语句都会提到最顶部来执行,这就是变量声明提升。 - 注意:只是声明提升,初始化并没有提升。
# 块级声明
ES6前是没有块级作用域的,比如 {}
外可以访问内部的变量。
- let 声明:声明变量、作用域限制在当前代码块、声明不会提升、禁止重声明(同一作用域不行,可以覆盖外部同名变量)。
var a = 123;
if (true) {
a = 'abc' // ReferenceError: Cannot access 'a' before initialization
let a;
}
1
2
3
4
5
2
3
4
5
- const 声明:声明常量、必须初始化、不可更改、作用域限制在当前代码块、声明不会提升、禁止重声明(同一作用域不行,可以覆盖外部同名变量)。如果用
const
来声明对象,则对象中的值可以修改。 - 临时死区(Temporal Dead Zone):JavaScript 引擎在扫描代码发现声明变量时,遇到
var
则提升到作用域顶部,遇到let
和const
则放到 TDZ 中。当执行了变量声明语句后,TDZ 中的变量才能正常访问。 - 全局块作用域绑定:在全局作用域下声明的时候,
var
会覆盖window对象中的属性、let
和const
会屏蔽,而不是覆盖,用window.
还能访问到。