JS基本数据类型
- 基础数据类型按值进行访问的,可以操作保存在变量中的实际值
- 引用数据类型,不允许直接访问值,不能直接操作对象的内存空间,在操作对象时,实际操作的是引用
存储方式
再看一下存储方式,结合深浅拷贝的定义就会理解一些了
- 基础类型存在栈中
- 引用类型同时保存在栈内存和堆内存
深拷贝和浅拷贝
浅拷贝
直接进行赋值
赋值引用 a 和 b 都指向同一个对象
1
2var a = [1, 2, 3];
var b = a;如果拷贝的是普通对象
Object.assign(target, source)
ES6 新增的对象方法,它可以实现第一层的“深拷贝”,但无法实现多层深拷贝
1
2
3var a = { name: "lion", age: 6 }
var c = {};
Object.assign(c, a);如果拷贝的是数组
Array.prototype.concat()
- ES6 扩展运算符
Array.prototype.slice()
1
2
3
4var a = [1, 2, 3];
var b = a.concat();
var [...c] = a;
var d = a.slice();没有递归的 for 循环
1
2
3
4
5
6
7
8
9
10
11let obj = {
name: 'bird',
age: 12,
arr: [10, 20, 30]
}
let obj2 = {}
for (let key in obj) {
if (!obj.hasOwnProperty(key)) break
obj2[key] = obj[key]
}
深拷贝
JSON.parse() 和 JSON.stringify
只能转换 JSON 支持的数据类型,可以参考 JSON 数据类型
bigint
不能直接转换为字符串- 对于
symbol/undefined/function
转换为字符串的时候就丢失了 - 正则对象、Error 错误对象会变为空对象,Date日期对象会变为字符串
- 无法处理 “套娃” 操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14let obj = {
// num: 10n, // Uncaught TypeError: Do not know how to serialize a BigInt
sy: Symbol('AA'),
un: undefined,
fn: function() {},
reg: /\d+/,
err: new Error('error'),
time: new Date(),
}
// obj.obj = obj // Uncaught TypeError: Converting circular structure to JSON
let obj2 = JSON.parse(JSON.stringify(obj))
console.log(obj2)
// { err: {}, reg: {}, time: "2020-07-10T01:43:11.344Z" }只能处理数字、字符串、布尔、null、object(普通对象/数组对象)…
递归赋值
Lodash/underscore 类库有 clone/deepClone
如下方法写是不行的,比如正则、错误对象、日期对象会变为普通对象
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
36let obj = {
name: 'bird',
age: 12,
arr: [10, 20, 30],
child: {
chinese: 90,
math: 100,
english: 80,
},
num: 10n,
sy: Symbol('AA'),
un: undefined,
ul: null,
fn: function() {},
reg: /\d+/,
err: new Error('error'),
time: new Date(),
}
function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : {}
if (obj && typeof obj === 'object') {
for (let key in obj) {
if (!obj.hasOwnProperty(key)) return
if (obj[key] && typeof obj[key] === 'object') {
objClone[key] = this.deepClone(obj[key])
} else {
objClone[key] = obj[key]
}
}
}
return objClone
}
let obj2 = deepClone(obj)
console.log(obj2)