变量的本质
栈(stack)的特性
- 结构性强,内存连续
- 寻址速度快
- 数据稳定
- 容量小
原始类型
- 原始类型存于栈中
- 原始类型不可修改; 无法直接修改指向内存中的值, 需要新开辟一块内存
类型 | typeof返回值 | 对象包装器 |
---|
Null | “object” | N/A |
Undefined | “undefined” | N/A |
Boolean | “boolean” | Boolean |
Number | “number” | Number |
BigInt | “bigint” | BigInt |
String | “string” | String |
Symbol | “symbol” | Symbol |
堆(heap)的特性
- 类似于书架
- 存储以坨为单位
- 容量大
- 不同数据间内存不连续
引用类型
- 在js中引用类型指的是对象(Object);
示例代码-01
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var b1 = 1, b2 = b1; b2 = b1; console.log(b1, b2);
var r1 = { a: 1, }, r2 = r1;
r2.a = 2; console.log(r1.a, r2.a)
|
字符串(特殊)
字符串本质上是存放在堆中,但是它是一个原始类型,原始类型不能直接修改栈中的数据,而是新建了一个标识符并指向了堆中的新数据
示例代码-02
1 2 3 4
| var a = 'hello word', b = a; b = 'hello'; consoel.log(a, b);
|
变量总结
知识总结
- 数据组织的方式不同 – 栈中的内存是连续的,堆中不是
- 用户权限不同 – 用户能读取栈中的数据不能读取堆中的数据
- 大小不同 – 栈的空间小堆的空间大
- 寻址速度不同 – 栈的寻址速度快而堆的寻址速度慢
- 作用不同 – 栈中存的是基本类型、引用类型的标识符以及字符串的标识符;堆中存放大小不确定的数据
值传递和引用传递
所谓的引用传递取决于传递的是值还是地址;在javascript中本质上就是值传递(读栈stack
内存中的值)
示例代码-01
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function change1(arg) { arg = 200; }
function change2(arg){ arg.a = 200; }
var foo = 100; var bar = { a: 100 };
change1(foo); change2(bar);
console.log(foo, bar);
|
深拷贝&浅拷贝
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| var person1 = { age: 28, hobby: '学习', son: { age: 3, hobby: 'drink milk', friends: ['jack', 'lucy'], }, }
function clone2(obj) { var clonePerson = {}; for(var key in obj) { clonePerson[key] = obj[key]; } return clonePerson; }
var newPerson = clonePerson(person1); newPerson.age = 18; console.log(person1.age); newPerson.son.age = 100; console.log(newPerson.son.age);
function clone2(obj) { if(typeof obj !== 'object' || obj === null) { return obj; }
var clone = Array.isArray(obj) ? [] : {}; for(var key in obj) { if(typeof obj[key] === 'object') { clone2(obj[key]) }else { clone[key] = obj[key]; } } return clone; }
|
垃圾回收
- stack存储基本变量和引用类型的指向;
- heap存储复杂数据和字符串;
- stack会自动回收,
heap借助垃圾回收机制进行回收,但需要一定的手动操作;
视频地址