-
基本数据类型:Undefined、Null、Boolean、Number、String5种基本数据类型,变量是直接按值存放的,存放在栈内存中的简单数据段,可以直接访问。
-
引用数据类型: 存放在堆内存中的对象,变量保存的是一个指针,这个指针指向另一个位置。当需要访问引用类型(如对象,数组等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。
首先我们应该思考的是为什么要有深浅拷贝,直接赋值它不香么?
直接赋值
- 直接赋值存在的问题
- 把对象赋值给一个变量,那么两者会指向同一个引用地址,其中一方改变,另一方也会相应改变
let foo = {
name:'宝儿姐',
quotes: ['社会我宝姐', '专业埋人','埋三送一']
}
let bar = foo
bar.name = 'aaa'
bar.quotes = []
console.log(foo) // {name: "aaa", quotes: []}
console.log(bar) // {name: "aaa", quotes: []}
浅拷贝
- 如果想拿到跟别人一模一样的数据,但是又不想影响别人的数据,这时候浅拷贝可以满足我们的需------仅限基本数据类型
- 浅拷贝:对于基本数据类型直接复制一份,对于引用类型则复制其地址,所以浅拷贝有一个问题,虽然基本类型不受影响,但是修改引用数据类型依然会影响原有的引用数据类型
- 通过 Object.assign()或者展开运算符可以实现
let foo = {
name:'宝儿姐',
quotes: {
title: '社会我宝姐/专业埋人/埋三送一'
}
}
let bar = Object.assign({}, foo) // 或者 let bar = {...foo}
bar.name = 'aaa'
bar.quotes.title = '社会宝儿姐,人美路子野'
console.log(foo) // {name: "宝儿姐", quotes: {title:'社会宝儿姐,人美路子野'} }
console.log(bar) // {name: "aaa", quotes: {title:'社会宝儿姐,人美路子野'}}
深拷贝
- 不管是基本数据类型还是引用数据类型,原对象和拷贝对象都不会互相影响
- 通过 JSON.parse(JSON.stringify()) 实现
- 存在的问题:1、会忽略 undefined 2、会忽略 symbol 3、对于正则表达式类型、函数类型等无法进行深拷贝
let foo = {
name:'宝儿姐',
quotes: {
title: '社会我宝姐/专业埋人/埋三送一'
}
}
let bar = JSON.parse(JSON.stringify(foo))
bar.name = 'aaa'
bar.quotes.title = '社会宝儿姐,人美路子野'
console.log(foo) // {name: "宝儿姐", quotes: {title:'社会我宝姐/专业埋人/埋三送一'} }
console.log(bar) // {name: "aaa", quotes: {title:'社会宝儿姐,人美路子野'}}
| 两对象是否指向同一内存地址 | 原基本数据类型是否被影响 | 原引用数据类型是否被影响 | |
|---|---|---|---|
| 赋值 | 是 | 是 | 是 |
| 浅拷贝 | 否 | 否 | 是 |
| 深拷贝 | 否 | 否 | 否 |