你真的搞明白JS的数据类型存储了吗?

77 阅读2分钟

数据类型

8大数据类型

  • Undefined
  • Null
  • Boolean
  • Number
  • String
  • Symbol
  • BigInt
  • Object
    • 包含普通对象-Object
    • 数组对象-Array
    • 正则对象-RegExp
    • 日期对象-Date
    • 数学函数-Math
    • 函数对象-Function

这些数据可以分为原始数据类型和引用数据类型:

  • 栈:原始数据类型(Undefined、Null、Boolean、Number、String、Symbol、BigInt)
  • 堆:引用数据类型(对象、数组和函数)

两种类型的区别在于存储位置的不同:

  • 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
  • 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
  1. "原始类型的数据是存放在栈中,引用类型的数据是存放在堆中的” 这是不对的。至少v8不是这样。浏览器引擎做了些性能优化:除了小的整数之外(Smi), 其他类型,包括string,都是在Heap上。另外像数字类型,很多时候也是在Heap上。具体参考: v8.dev/blog/react-… "For small integers in the 31-bit signed integer range, V8 uses a special representation calle d Smi. Anything that is not a Smi is represented as a HeapObject, which is the address of so me entity in memory. " 这里v8的文档里面也有讲: developer.chrome.com/docs/devtoo…
  2. "原始类型的赋值会完整复制变量值,而引用类型的赋值是复制引用地址。" 这也是错的。因为string interning的存在,string literals都存在constant pool(常量池)里,const a = 'foo'; const b =foo 这里内存里面不会有两个字符串foo, 被复制不是string的值,而是constant pool pointer.(常量池的指针)

总结:

浏览器引擎做了些性能优化:除了小的整数之外(Smi), 其他类型,包括string,都是在常量池(堆)中。