Blog
Blog copied to clipboard
变量和类型 - 变量在内存中的具体存储形式
变量在内存中的具体存储形式
基本类型变量的存储
- 基本类型变量存储在栈内存中;
- JS中基本类型值是不可变的,故基本类型变量改变时都会为变量重新分配内存并存储值。
下面例子说明了基本类型变量的声明、赋值及改变的过程。
// Step 1. `myNumber` -> Address: 0012CCGWH80 -> Value: 23
let myNumber = 23
// Step 2. `newVar` -> Address: 0012CCGWH80 -> Value: 23
let newVar = myNumber
// Step 3. `myNumber` -> Address: 0034AAAAH23 -> Value: 24
myNumber = myNumber + 1
栈内存 与 堆内存
在JavaScript
内存模型中,内存空间分为 栈内存(Stack) 与 堆内存(Heap) 两种。
展开查看栈内存、堆内存的特点
栈内存特点
- 存储的值大小固定
- 空间较小
- 可以直接操作其保存的变量,运行效率高
- 由系统自动分配存储空间
堆内存特点
- 存储的值大小不定,可动态调整
- 空间较大,运行效率低
- 无法直接操作其内部存储,使用引用地址读取
- 通过代码进行分配空间
引用类型变量的存储
- 引用类型变量(即
Object
类型)存储在堆内存中; - 堆内存中存储的引用类型变量值是可变的。
下面例子说明了引用类型变量的声明、赋值及改变的过程。
// Step 1. `myArray` -> HeapAddress: 22VVCX011 -> Value: []
let myArray = []
// Step 2. `myArray` -> HeapAddress: 22VVCX011 -> Value: ['first', 'second', 'third']
myArray.push('first')
myArray.push('second')
myArray.push('third')
变量的比较与传递
变量的比较,是按变量在栈内存中的值进行比较,
变量的拷贝与变量作为函数参数进行传递,也是按变量在栈内存中的值进行传递。
- 对于基本类型变量来说,栈内存中的值即为其值本身;
- 对于引用类型变量来说,栈内存中的值即为指向堆内存中引用类型值的地址。
// 变量比较
const num1 = 12
const num2 = 12
expect(num1 === num2).toBe(true)
const obj1 = { foo: 'foo' }
const obj2 = obj1
const obj3 = { foo: 'foo' }
expect(obj1 === obj2).toBe(true)
expect(obj1 === obj3).toBe(false)
// 变量传递
const changeNum = (num) => num++
const changeObj = (obj) => (obj = { foo: 'bar' })
const changeObjProp = (obj) => (obj.foo = 'bar')
const num = 1
changeNum(num)
expect(num).toBe(1)
const obj1 = { foo: 'foo' }
const obj2 = { foo: 'foo' }
changeObjProp(obj1)
expect(obj1).toEqual({ foo: 'bar' })
changeObj(obj2)
expect(obj2).toEqual({ foo: 'foo' })
const num = 1
changeNum(num)
expect(num).toBe(1)
请问为啥这里的changeNum(num)也是1呢?
@lixialu 因为在changeNum(num)
调用时,num
只是作为一个值传入了changeNum
,然后changeNum
内部初始化了一个num
变量,被复制1,自增到2,返回,但是调用的地方没有接函数返回值,这个2也就被垃圾回收了