定义一个对象构造函数
function User (username, password, age, address) {
this.username = username;
this.password = password;
this.age = age;
this.address = address;
}
定义一个方法:将对象转化为JOSN字符串输出
const getJosnString = (obj) =>{
console.log(JSON.stringify(obj));
}
浅拷贝
使用 “=” 直接赋值
*使用 = 直接赋值会直接赋值对象的引用
* 假设originalObj对象的地址为 -> 0x0001
* 通过 = 直接把originalObj对象赋值给shallowCopyObj对象
* originalObj对象的地址 -> 0x0001
* shallowCopyObj对象的地址 -> 0x0001
* 两个对象的引用是一样,使用无论对哪个对象属性进行更改的时候,两个对象中属性值都会发生改变
//浅拷贝 使用 = 直接赋值
(() => {
/**
* 使用 = 直接赋值会直接赋值对象的引用
* 假设originalObj对象的地址为 -> 0x0001
* 通过 = 直接把originalObj对象赋值给shallowCopyObj对象
* originalObj对象的地址 -> 0x0001
* shallowCopyObj对象的地址 -> 0x0001
* 两个对象的引用是一样,使用无论对哪个对象属性进行更改的时候,两个对象中属性值都会发生改变
*/
const originalObj = new User('wang', '123321', 123, {gz: '广州',sz: '深圳',sh: '上海'} ) ;
const shallowCopyObj = originalObj ;
//true
console.log(originalObj === shallowCopyObj );
//true
console.log(originalObj.address === shallowCopyObj.address);
//输出原对象和拷贝的对象
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
//对原对象的基本数据类型age属性进行更改
originalObj.age = 20;
//{"username":"wang","password":"123321","age":20,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":20,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
//对拷贝后的对象的基本数据类型age属性进行更改
shallowCopyObj.age = 40
//{"username":"wang","password":"123321","age":40,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
//修改原对象引用数据类型address属性
originalObj.address.gz = '白云'
//{"username":"wang","password":"123321","age":40,"address":{"gz":"白云","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"白云","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
//修改拷贝后对象引用数据类型address属性
shallowCopyObj.address.gz = '天河'
//{"username":"wang","password":"123321","age":40,"address":{"gz":"天河","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"天河","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
})();
使用Object.assign(a, b)方法
* 使用Object.assign(a, b)方法实现浅拷贝的时候
* js中会创建一个新的对象,将新对象的地址赋值给shallowCopyObj对象
* 假如 originalObj -> 0x0001
* 即使用Object.assign(a, b)方法实现浅拷贝后
* originalObj -> 0x0001
* shallowCopyObj -> 0x0002
*
* 0x0001 -> {
* username: "wang",
* password: "123321",
* age: 123,
* address: -> 0x0003
* }
*
* 0x0002 -> {
* username: "wang",
* password: "123321",
* age: 123,
* address: -> 0x0003
* }
*
* 0x0003 -> {
* gz: '广州',
* sz: '深圳',
* sh: '上海'
* }
* 当我们修改两个对象中基本数据类型age时,两个对象的值时互不影响的
* 当我们修改两个对象中引用数据类型属性address时,因为他们指向的地址是一致的,两个对象都会影响
//浅拷贝 Object.assign(a, b)方法 将 b 对象拷贝给 a 对象 返回值拷贝后的对象
(() => {
/**
* 使用Object.assign(a, b)方法实现浅拷贝的时候
* js中会创建一个新的对象,将新对象的地址赋值给shallowCopyObj对象
* 假如 originalObj -> 0x0001
* 即使用Object.assign(a, b)方法实现浅拷贝后
* originalObj -> 0x0001
* shallowCopyObj -> 0x0002
*
* 0x0001 -> {
* username: "wang",
* password: "123321",
* age: 123,
* address: -> 0x0003
* }
*
* 0x0002 -> {
* username: "wang",
* password: "123321",
* age: 123,
* address: -> 0x0003
* }
*
* 0x0003 -> {
* gz: '广州',
* sz: '深圳',
* sh: '上海'
* }
* 当我们修改两个对象中基本数据类型age时,两个对象的值时互不影响的
* 当我们修改两个对象中引用数据类型属性address时,因为他们指向的地址是一致的,两个对象都会影响
*
*/
const a ={
username: "wang",
password: "123321",
}
const b = {
age: 21,
address: {}
}
const c = Object.assign(a, b)
//{"username":"wang","password":"123321","age":21,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(a)
//{"age":21,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(b)
//{"username":"wang","password":"123321","age":21,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(c)
const originalObj = new User('wang', '123321', 123, {gz: '广州',sz: '深圳',sh: '上海'} ) ;
const shallowCopyObj = Object.assign({}, originalObj) ;
//false
console.log(originalObj === shallowCopyObj);
//true
console.log(originalObj.address === shallowCopyObj.address);
//输出原对象和拷贝后的对象
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
//对原对象的基本数据类型age属性进行更改
originalObj.age = 20;
//{"username":"wang","password":"123321","age":20,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
//对拷贝后的对象的基本数据类型age属性进行更改
shallowCopyObj.age = 40
//{"username":"wang","password":"123321","age":20,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
//修改原对象引用数据类型address属性
originalObj.address.gz = '白云'
//{"username":"wang","password":"123321","age":20,"address":{"gz":"白云","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"白云","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
//修改拷贝后对象引用数据类型address属性
shallowCopyObj.address.gz = '天河'
//{"username":"wang","password":"123321","age":20,"address":{"gz":"天河","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"天河","sz":"深圳","sh":"上海"}}
getJosnString(shallowCopyObj)
})();
深拷贝
JOSN.parse(JOSN.stringify())方法
* 使用JOSN.parse(JOSN.stringify(obj))方法实现深拷贝时
* js中会创建一个新的对象,将新对象的地址赋值给deepCopyObj对象
* 假如 originalObj -> 0x0001
* 即使用JOSN.parse(JOSN.stringify(obj))方法实现浅拷贝后
* originalObj -> 0x0001
* shallowCopyObj -> 0x0002
*
* 0x0001 -> {
* username: "wang",
* password: "123321",
* age: 123,
* address: -> 0x0003
* }
*
* 0x0002 -> {
* username: "wang",
* password: "123321",
* age: 123,
* address: -> 0x0004
* }
*
* 0x0003 -> {
* gz: '广州',
* sz: '深圳',
* sh: '上海'
* }
*
* 0x0004 -> {
* gz: '广州',
* sz: '深圳',
* sh: '上海'
* }
*
* 当我们修改两个对象中基本数据类型age时,两个对象的值时互不影响的
* 当我们修改两个对象中引用数据类型属性address时,因为他们指向的地址是一致的,两个对象的值时互不影响
*
* 通过这个方法可以实现深拷贝,但是这个方法是不值得推荐的
* 原因:
* 1、无法拷贝特殊对象:JSON.stringify() 方法默认会忽略掉一些特殊对象的属性,
* 例如函数、正则表达式、Symbol 等。这意味着通过 JSON.parse(JSON.stringify(obj))
* 无法完全拷贝包含这些特殊对象的对象。
* 2、无法处理循环引用:如果对象存在循环引用(即对象内部存在相互引用关系),
* 则 JSON.stringify() 会报错,因为 JSON 格式不支持循环引用。
* 因此,这种方式无法正确处理包含循环引用的对象。
* 3、丢失原型链:通过 JSON.parse(JSON.stringify(obj))
* 深拷贝的对象会失去原型链上的信息。拷贝后的对象的原型将变成 Object.prototype,
* 而不再是原始对象的原型。
* 4、效率问题:将对象转换为 JSON 字符串,然后再解析成对象的过程是相对耗时的操作,
* 特别是对于大型对象或嵌套层次很深的对象,会带来性能上的损耗
*
* 推荐使用lodash.js中的cloneDeep()方法可以解决以上问题
//使用JOSN.parse(JOSN.stringify(obj))方法实现深拷贝 返回值为拷贝后的对象
(() => {
/**
* 使用JOSN.parse(JOSN.stringify(obj))方法实现深拷贝时
* js中会创建一个新的对象,将新对象的地址赋值给deepCopyObj对象
* 假如 originalObj -> 0x0001
* 即使用JOSN.parse(JOSN.stringify(obj))方法实现浅拷贝后
* originalObj -> 0x0001
* shallowCopyObj -> 0x0002
*
* 0x0001 -> {
* username: "wang",
* password: "123321",
* age: 123,
* address: -> 0x0003
* }
*
* 0x0002 -> {
* username: "wang",
* password: "123321",
* age: 123,
* address: -> 0x0004
* }
*
* 0x0003 -> {
* gz: '广州',
* sz: '深圳',
* sh: '上海'
* }
*
* 0x0004 -> {
* gz: '广州',
* sz: '深圳',
* sh: '上海'
* }
*
* 当我们修改两个对象中基本数据类型age时,两个对象的值时互不影响的
* 当我们修改两个对象中引用数据类型属性address时,因为他们指向的地址是一致的,两个对象的值时互不影响
*
* 通过这个方法可以实现深拷贝,但是这个方法是不值得推荐的
* 原因:
* 1、无法拷贝特殊对象:JSON.stringify() 方法默认会忽略掉一些特殊对象的属性,
* 例如函数、正则表达式、Symbol 等。这意味着通过 JSON.parse(JSON.stringify(obj))
* 无法完全拷贝包含这些特殊对象的对象。
* 2、无法处理循环引用:如果对象存在循环引用(即对象内部存在相互引用关系),
* 则 JSON.stringify() 会报错,因为 JSON 格式不支持循环引用。
* 因此,这种方式无法正确处理包含循环引用的对象。
* 3、丢失原型链:通过 JSON.parse(JSON.stringify(obj))
* 深拷贝的对象会失去原型链上的信息。拷贝后的对象的原型将变成 Object.prototype,
* 而不再是原始对象的原型。
* 4、效率问题:将对象转换为 JSON 字符串,然后再解析成对象的过程是相对耗时的操作,
* 特别是对于大型对象或嵌套层次很深的对象,会带来性能上的损耗
*
* 推荐使用lodash.js中的cloneDeep()方法可以解决以上问题
*
*/
const originalObj = new User('wang', '123321', 123, {gz: '广州',sz: '深圳',sh: '上海'} ) ;
const deepCopyObj = JSON.parse(JSON.stringify(originalObj));
//false
console.log(originalObj === deepCopyObj);
//false
console.log(originalObj.address === deepCopyObj.address);
//输出原对象和拷贝后的对象
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//对原对象的基本数据类型age属性进行更改
originalObj.age = 20;
//{"username":"wang","password":"123321","age":20,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//对拷贝后的对象的基本数据类型age属性进行更改
deepCopyObj.age = 40
//{"username":"wang","password":"123321","age":20,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//修改原对象引用数据类型address属性
originalObj.address.gz = '白云'
//{"username":"wang","password":"123321","age":20,"address":{"gz":"白云","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//修改拷贝后对象引用数据类型address属性
deepCopyObj.address.gz = '天河'
//{"username":"wang","password":"123321","age":20,"address":{"gz":"白云","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"天河","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//ƒ Object() { [native code] }
console.log(deepCopyObj.__proto__.constructor);
})();
lodash.js中_.cloneDeep()方法
//使用lodash.js中_.cloneDeep()方法
(() => {
const originalObj = new User('wang', '123321', 123, {gz: '广州',sz: '深圳',sh: '上海'} ) ;
const deepCopyObj = _.cloneDeep(originalObj);
//false
console.log(originalObj === deepCopyObj);
//false
console.log(originalObj.address === deepCopyObj.address)
//输出原对象和拷贝后的对象
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//对原对象的基本数据类型age属性进行更改
originalObj.age = 20;
//{"username":"wang","password":"123321","age":20,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":123,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//对拷贝后的对象的基本数据类型age属性进行更改
deepCopyObj.age = 40
//{"username":"wang","password":"123321","age":20,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//修改原对象引用数据类型address属性
originalObj.address.gz = '白云'
//{"username":"wang","password":"123321","age":20,"address":{"gz":"白云","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"广州","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
//修改拷贝后对象引用数据类型address属性
deepCopyObj.address.gz = '天河'
//{"username":"wang","password":"123321","age":20,"address":{"gz":"白云","sz":"深圳","sh":"上海"}}
getJosnString(originalObj)
//{"username":"wang","password":"123321","age":40,"address":{"gz":"天河","sz":"深圳","sh":"上海"}}
getJosnString(deepCopyObj)
/**
* ƒ User (username, password, age, address) {
this.username = username;
this.password = password;
this.age = age;
this.address = address;
}
*/
console.log(deepCopyObj.__proto__.constructor);
})();