返回

从栈与堆深入理解 JavaScript 变量存储机制

前端

如果问出这个问题“JavaScript 的变量存储机制”,在百度上进行一番搜索,你可能会看到不少回答都是:对于原始类型,数据本身是存在栈内,对于对象类型,在栈中存的只是一个堆内地址的引用。

想要透彻理解 JavaScript 的变量存储机制,首先要弄明白栈和堆的概念,以及 JavaScript 作用域、值传递和引用传递的概念。

栈与堆:内存中的两块领地

在计算机科学中,栈和堆是内存中的两块特定区域,用于存储不同的数据类型。

  • 栈: 栈是一种先进后出(LIFO)的数据结构,这意味着最后存储的数据总是最先被取出。栈通常用于存储局部变量、函数参数以及函数的返回值。
  • 堆: 堆是一种后进先出(FIFO)的数据结构,这意味着最早存储的数据总是最先被取出。堆通常用于存储动态分配的对象以及数组。

JavaScript 变量的存储方式

在 JavaScript 中,变量可以分为两种类型:原始类型和对象类型。原始类型包括数字、字符串、布尔值、null 和 undefined。对象类型包括对象、数组和函数。

  • 原始类型变量: 原始类型变量直接存储在栈中。这意味着它们的值是直接存储在内存中的,而不是通过引用来指向其他地方。
  • 对象类型变量: 对象类型变量的存储方式则有所不同。它们的值不是直接存储在栈中,而是一个指向堆中存储的实际对象的指针。也就是说,对象类型变量实际上存储的是一个引用,指向堆中存储的实际对象。

JavaScript 作用域与变量存储

在 JavaScript 中,作用域决定了变量的可见范围。作用域可以分为全局作用域和局部作用域。全局作用域是指整个程序都可以访问的变量,而局部作用域是指只在函数内部可以访问的变量。

  • 全局变量: 全局变量存储在全局作用域中,可以在程序的任何地方访问。
  • 局部变量: 局部变量存储在局部作用域中,只能在声明它们的函数内部访问。

JavaScript 值传递与引用传递

在 JavaScript 中,函数参数的传递方式可以分为值传递和引用传递。

  • 值传递: 当一个原始类型变量作为函数参数传递时,传递的是变量的副本。这意味着函数内部对变量值的任何修改都不会影响到函数外部的原始变量。
  • 引用传递: 当一个对象类型变量作为函数参数传递时,传递的是变量的引用。这意味着函数内部对变量值的任何修改都会影响到函数外部的原始变量。

通过理解栈、堆、作用域、值传递和引用传递的概念,我们就可以全面理解 JavaScript 变量的存储机制。