公众号:程序员波波
JS中对于对象类型(包括数组和字典),赋值效果和C++中指针一样,都是指向了同一块内存的对象,所以修改操作相当于是连带的,
如果b={x1, x2, x3};a = b
那么修改a.x1,最终打印出来的b.x1也会变化,因为没有新的对象生成,它们指向的都是同一个对象。
但是对于基本类型number,string,它们的赋值就是相当于拷贝,两个变量是独立的。
说白了,就是JS中所有的赋值都是拷贝,但是对象的拷贝,相当于拷贝的是内存地址,但是该地址所代表的对象只有一个。
----------------------------------------------
这样就会遇到一个问题,我想完完整整的拷贝一个对象(对象的整个树形子元素全部拷贝下来),也就是所谓的深拷贝。
基本上使用递归就可以实现,从根节点递归每一层下去拷贝,直到非对象类型。
同样的我想比较两个对象,但是这两个对象可能是树形上相同,节点中对象的地址不一定相同,在这记作深比较。
和深拷贝类似,采用递归,一层一层比较下去,每一个键值进行递归,直到非对象类型,直接比较值是否相等。
class Tools
{
static deepCopyObject(obj) {
let objClone = null
if (obj && typeof obj === "object") {
objClone = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
objClone[key] = Tools.deepCopyObject(obj[key]);
}
}
}
else {
objClone = obj
}
return objClone;
}
static objectDeepEqual(obj1, obj2) {
if (obj1 && typeof obj1 === "object" && obj2 && typeof obj2 === 'object') {
if (Array.isArray(obj1) && !Array.isArray(obj2)) {
return false
}
if (!Array.isArray(obj1) && Array.isArray(obj2)) {
return false
}
for (let key in obj1) {
if (obj1.hasOwnProperty(key)) {
if (!obj2.hasOwnProperty(key)) {
return false
}
}
}
for (let key in obj2) {
if (obj2.hasOwnProperty(key)) {
if (!obj1.hasOwnProperty(key)) {
return false
}
}
}
for (let key in obj1) {
if (obj1.hasOwnProperty(key)) {
if (!Tools.objectDeepEqual(obj1[key], obj2[key])) {
return false
}
}
}
return true
}
else {
return obj1 == obj2
}
}
}