JavaScript基础

2021/5/20 JavaScript

# 1. 数据类型

JavaScript 中基本数据类型和引用数据类型是如何存储的

在刚开始学习程序设计的时候没有在意内存这些基础知识,导致后来在提到“什么什么是存在栈中的,栈中只是存了一个引用”这样的话时总是一脸懵逼。后来渐渐的了解了一些内存的知识,这部分还是非常有必要了解的。

# 基本数据结构

  • 栈:只允许在一段进行插入或者删除操作的线性表,是一种先进后出的数据结构。
  • 堆:是基于散列算法的数据结构。
  • 队列:是一种先进先出(FIFO)的数据结构。

# JavaScript 中数据类型的存储

JavaScript 中将数据类型分为基本数据类型和引用数据类型,它们其中有一个区别就是存储的位置不同。

# 基本数据类型

我们都知道 JavaScript 中的基本数据类型有:

  • String
  • Number
  • Boolean
  • Undefined
  • Null
  • Symbol(暂时不管)

基本数据类型都是一些简单的数据段,它们是存储在栈内存中。

# 引用数据类型

JavaScript 中的引用数据类型有:

  • Array
  • object

引用数据类型是保存在堆内存中的,然后再栈内存中保存一个对堆内存中实际对象的引用。所以,JavaScript中对引用数据类型的操作都是操作对象的引用而不是实际的对象。

可以理解为,栈内存中保存了一个地址,这个地址和堆内存中的实际值是相关的。

# 复制

基本数据类型:对于基本数据类型,如果进行复制,系统会自动为新的变量在栈内存中分配一个新值,很容易理解。

引用数据类型:如果对于数组、对象这样的引用数据类型而言,复制的时候就会有所区别了。系统也会自动为新的变量在栈内存中分配一个值,但这个值仅仅是一个地址。也就是说,复制出来的变量和原有的变量具有相同的地址值,指向堆内存中的同一个对象。

# 为什么?

为什么基本数据类型存在栈中,而引用数据类型存在堆中呢?

  1. 堆比栈大,栈比对速度快。
  2. 基本数据类型比较稳定,而且相对来说占用的内存小。
  3. 引用数据类型大小是动态的,而且是无限的。
  4. 堆内存是无序存储,可以根据引用直接获取。

# 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
  • const 声明:声明常量、必须初始化、不可更改、作用域限制在当前代码块、声明不会提升、禁止重声明(同一作用域不行,可以覆盖外部同名变量)。如果用 const 来声明对象,则对象中的值可以修改。
  • 临时死区(Temporal Dead Zone):JavaScript 引擎在扫描代码发现声明变量时,遇到 var 则提升到作用域顶部,遇到 letconst 则放到 TDZ 中。当执行了变量声明语句后,TDZ 中的变量才能正常访问。
  • 全局块作用域绑定:在全局作用域下声明的时候,var 会覆盖window对象中的属性、letconst 会屏蔽,而不是覆盖,用 window. 还能访问到。
Last Updated: 2023/04/22, 23:39:26
彩虹
周杰伦