JS中的数据类型包括基本数据类型和引用数据类型

  • 基本数据类型:undefinednullbooleannumberstringsymbol
  • 引用数据类型:objectarrayfunction

基本数据类型

基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以分配,它们是直接按值存放的,所以可以直接按值访问

1
2
3
4
5
6
var x = 1
var y = x
y = 2
console.log(x) //1
console.log(y) //2

引用数据类型

引用类型数据在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存中堆内存中的对象。

1
2
3
4
5
6
7
8
9
10
var a = [1,2,3,4,5];
var b = a;//传址 ,对象中传给变量的数据是引用类型的,会存储在堆中;
var c = a[0];//传值,把对象中的属性/数组中的数组项赋值给变量,这时变量C是基本数据类型,存储在栈内存中;改变栈中的数据不会影响堆中的数据
console.log(b);//1,2,3,4,5
console.log(c);//1
//接下来改变数值
b[4] = 6;
c = 7;
console.log(a[4]);//6
console.log(a[0]);//1

浅拷贝

自定义浅拷贝函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var a = { key1: "11111", key2: ["你", "我"] }

const Copy = (p) => {
var c = {}
for (var i in p) {
console.log(i)
c[i] = p[i]
}
return c
}

var b = Copy(a);

a.key1 = "22222"
console.log(b.key1) //11111

a.key2.push("我是A") //这里没有拷贝过去,这是第二层
b.key2.push("我是B") //这里没有拷贝过去,这是第二层
b.key3 = ["我是b的key3添加的值"]

console.log(a,b)

其他浅拷贝方式

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
//ES6实现浅拷贝的方法
var a = { name: "暖风" }
var b = Object.assign({}, a);
b.age = 18;
console.log(a.age); //undefined


// 数组
var a = [1, 2, 3];
var b = a.slice();
a.push(4)
console.log(a)
console.log(b)


var a = [1, 2, 3];
var b = a.concat();
b.push(4);
console.log(b)//1,2,3,4
console.log(a)//1,2,4


var a = [1, 2, 3];
var b = [...a]
console.log(b)//1,2,3,4
console.log(a)//1,2,4

深拷贝

如果对象属性值类型是数组和或象时只会传址,那么我们就用递归来解决

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
var a = {
age: 22,
name: {
name1: "小蜜蜂",
name2: "wesley"
}
}
const deepCopy = (a, c) => {
var c = c || {}
for(var i in a){
console.log(i)
if(typeof a[i] === "object"){ //如果属性值为对象或者数组
c[i] = a[i].constructor === Array ? [] : {}
// console.log(c[i])
deepCopy(a[i], c[i])
}else{
c[i] = a[i]
}
}
return c
}
b = deepCopy(a)

a.name.name3 = "sjw"
console.log(a)
console.log(b)