抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

  1. 变量的本质
  2. 深拷贝
  3. 垃圾回收

变量的本质

栈(stack)的特性

  1. 结构性强,内存连续
  2. 寻址速度快
  3. 数据稳定
  4. 容量小

原始类型

  1. 原始类型存于栈中
  2. 原始类型不可修改; 无法直接修改指向内存中的值, 需要新开辟一块内存
类型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)的特性

  1. 类似于书架
  2. 存储以坨为单位
  3. 容量大
  4. 不同数据间内存不连续

引用类型

  1. 在js中引用类型指的是对象(Object);

示例代码-01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var 
b1 = 1,
b2 = b1; // RHS right head-side search 右查询(本质:读了内存中存的值)
b2 = b1; // 本质是在内存中指向了新的数据(2),旧数据(1)将被回收
console.log(b1, b2);

var
r1 = {
a: 1,
},
r2 = r1; // 程序本身只允许访问栈,无法访问堆;栈和堆通过标识符建立连接

r2.a = 2; // 因为r1和r2同时指向了堆中的数据,所以修改r2,r1随之改变
console.log(r1.a, r2.a)

字符串(特殊)

字符串本质上是存放在堆中,但是它是一个原始类型,原始类型不能直接修改栈中的数据,而是新建了一个标识符并指向了堆中的新数据

示例代码-02

1
2
3
4
var a = 'hello word',
b = a;
b = 'hello'; // 栈中会新建标识符指向新数据,旧数据则被回收
consoel.log(a, b);

变量总结

知识总结

  1. 数据组织的方式不同 – 栈中的内存是连续的,堆中不是
  2. 用户权限不同 – 用户能读取栈中的数据不能读取堆中的数据
  3. 大小不同 – 栈的空间小堆的空间大
  4. 寻址速度不同 – 栈的寻址速度快而堆的寻址速度慢
  5. 作用不同 – 栈中存的是基本类型、引用类型的标识符以及字符串的标识符;堆中存放大小不确定的数据

值传递和引用传递

所谓的引用传递取决于传递的是值还是地址;在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; // 会改变,son是一个object属于引用类型存放于堆中,newPerson.son和person1.son指向同一个
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;
}

垃圾回收

  1. stack存储基本变量和引用类型的指向;
  2. heap存储复杂数据和字符串;
  3. stack会自动回收,
    heap借助垃圾回收机制进行回收,但需要一定的手动操作;

视频地址

评论