1、数据类型
数据类型分为:基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型(Array、Object)
区别:基本数据类型的值存储在栈内存,引用数据类型存储在堆内存里
深入分析: 因为值类型直接赋值内存比较小,对造成的性能不会有问题,所以可以直接赋值 而引用类型的json可以是上千上万行代码,一般造成内存比较大, 因此也需要将栈和堆严格分离出来,引用类型如果像值类型一样直接存储复制值 会非常占内存、耗时
2、概念
浅拷贝:拷贝就是复制,就相当于把一个对象中的所有的内容,复制一份给另一个对象, 直接复制,或者说,就是把一个对象的地址给了另一个对象,他们指向相同,两个对象之间有共同的属性或者方法,都可以使用(相互会发生影响)
深拷贝:把堆中的内容复制一份,内容改变不会相互影响。(各自独立的)
通俗点就是,浅拷贝是指对象复制的时候只复制一层;深拷贝是指复制对象的所有层级
3、要弄明白的几个问题
1、浅拷贝和深拷贝的区别
2、浅拷贝实现方式
(1)Object.assign()方法
概念:用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
用法:Object.assign(obj1,obj2):obj1是目标对象,obj2是源对象(后面可以接多个参数),最后返回obj1目标对象 (此方法类似于将对象合并,如果参obj1与obj2的key值相同,obj2的值会覆盖obj1)
let obj1 ={
name:'小江',
sex:'男',
car:{
a:"丰田"
}
}
let obj2 ={
name:'小明',
sex:'女',
age:23
}
let assign = Object.assign(obj1,obj2);
assign.a = "宝马"
console.log(assign); // {name: '小明', sex: '女', car: {a:'丰田'}, age: 23, a: '宝马'}
console.log(obj1); // {name: '小明', sex: '女', car: {a:'丰田'}, age: 23, a: '宝马'}
// assign和obj1值是一样的,返回目标对象。
注:Object.assign() 拷贝的是属性值,只实现了对第一层的深拷贝,所以也算是浅拷贝的一种
(2)使用jQuery中的$.extend()
var obj = {
name: '小江',
age: 25,
sex: '男',
hobby: {
a: '111'
}
}
var extend = {};
$.extend(extend, obj); //将obj复制到新对象中
console.log(extend) //{name: '小江', age: 25, sex: '男', hobby: {a:'111'}};
3、如何手写深拷贝(递归)
// 定义一串数据
const obj1 = {
name: 'zhangsan',
age: 23,
city: 'shenzhen',
arr: ['a', 'b', 'c'],
object: {
x: {
z: 1000
}
}
}
// 使用深拷贝
const obj2 = deepLoop(obj1)
obj2.city = 'beijing'
console.log(obj1.city); //shenzhen (数据各自独立)
console.log(obj2.city); //beijing (数据各自独立)
function deepLoop(obj = {}) {
//先判断是不是空值 和 是不是对象 , 不是 则返回
if (typeof obj !== 'object' || obj == null) {
return obj
}
// 定义一个放 存储结果 的空值
var result
// 使用 instanceof 来判断obj是否为数组
if (obj instanceof Array) {
result = []
} else {
result = {}
}
// for in 循环遍历 然后进行递归!
for (let key in obj) {
// 需要保证key 不是原型的属性
if (obj.hasOwnProperty(key)) {
result[key] = deepLoop(obj[key])
}
}
return result
}