原生的Object.assign(target, src)
方法来实现浅拷贝:Object.assign({},ab)
扩展运算符:{...ab}

常用的深拷贝:
let newObj = JSON.parse(JSON.stringify(oldObj))
(只适合普通数据类型,怕环形对象,怕function 等一些特定数据结构)
var ov={
a:{
b:{
c:{arr:[1,2,3]}
}
}
}
var ob = JSON.parse(JSON.stringify(ov))
// a:b:c:arr: (3) [1, 2, 3]
var obj2 = { // 环形对象
to:obj1
}
obj1.to = obj2;
// 这种就会报错
深拷贝对象和数组时:
function deepClone(obj) {
if (!obj || typeof obj !== 'object') return
let newObj = Array.isArray(obj) ? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] =
typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
}
}
return newObj
}
对于所有的对象类型深拷贝:
let obj1 = {
// typeof 数组|对象 => 'object'
// Array.isArray()
arr: [1, 2, 3],
arrayOfObjs: [{ c: 5 }, { d: 6 }],
date: new Date(),
object: { val: 4 },
// 增加一个属性
fn: function () { // typeof fn ===> 'function'
return 5;
},
set: new Set([7, 8, 9, { e: 10 }]),
map: new Map([
[11, 'f'],
[12, 'g']
]),
reg: /[h-z]/
};
let wm = new WeakMap();
function deepClone(obj) {
// 基本数据类型 和函数处理, null
// function f (){}
// typeof f => 'function'
if (obj === null || typeof obj !== 'object') {
// 直接返回
return obj
}
// 如果缓存中已经存在该对象则不继续操作 WeakMap
if (wm.has(obj)) {
return wm.get(obj)
}
// 处理Map
// 处理Set
// 处理RexExp
if (obj instanceof Map) {
var tmp = new Map();
wm.set(obj,tmp);
for (var values of obj) {
var key = values[0];
var val = values[1];
tmp.set(key, deepClone(val));
}
return tmp;
} else if (obj instanceof Set) {
var tmp = new Set();
wm.set(obj,tmp);
for (var val of obj) {
tmp.add(deepClone(val));
}
return tmp;
} else if (obj instanceof RegExp) {
var tmp = new RegExp(obj);
wm.set(obj,tmp);
return tmp;
} else {
// 处理数组、对象、Date
var tmp = new obj.constructor();
wm.set(obj,tmp);
for(var key in obj){
tmp[key] = deepClone(obj[key]);
}
return tmp;
}
}
Number String Boolean undefined Null Object (Array)Function
基本类型:Number Boolean String undefined null
引用类型:Object (Array) Function
基本类型
的数据是存放在栈内存
中的,而引用类型
的数据是存放在堆内存
中的,引用类型会导致深浅拷贝的问题
基本类型
基本类型的变量是存放在栈内存(Stack)里的
基本数据类型的值是按值访问的
基本类型的值是不可变的
基本类型的比较是它们的值的比较
引用类型
引用类型的值是保存在堆内存(Heap)中的对象(Object)
引用类型的值是按引用访问的
引用类型的值是可变的
引用类型的比较是引用的比较
var p = 1;
var p1 = p;
基本类型的复制就是在栈内存中开辟出了一个新的存储区域用来存储新的变量,
这个变量有它自己的值,只不过和前面的值一样,所以如果其中一个的值改变,则不会影响到另一个。

var object1 = new Object();
var object2 = object1;
定义了一个对象其实是在栈内存中存储了一个指针,这个指针指向堆内存中该对象的存储地址。
复制给另一个对象的过程其实是把该对象的地址复制给了另一个对象变量,两个指针都指向同一个对象,
所以若其中一个修改了,则另一个也会改变。

String Boolean Number
这三种类型也叫做 基本包装类型
有方法可以使用
网友评论