小算法|关于对象的深复制

小算法 | 关于对象深复制

way1

(() => {
function copyObj(obj) {
var copyObj = {};
for (let key of Object.keys(obj)) {
//引用类型
if (obj[key] instanceof Object) {
let toString = Object.prototype.toString;
let objtype = toString.call(obj[key])
let objvalue = obj[key].toString();
/***
*
* 对于几种特殊的 引用类型需要额外处理下,Date 类型, 正则类型等.
*
* Math 类型,不需要处理, 因为 Math 属于 global 类型的(属于设计模式中的单体模型).
*
* null undefined 类型可以不用处理,是因为,for...of 循环 可处理,不会像 forin,forEach 跳过.
*
* toString.call(new Date); // [object Date]
* toString.call(new String); // [object String]
* toString.call(Math); // [object Math] //Since JavaScript 1.8.5
* toString.call(undefined); // [object Undefined]
* toString.call(null); // [object Null]
*
*/
if (objtype.indexOf("Date") > -1) {
copyObj[key] = new Date(objvalue);
}
if (objtype.indexOf("String") > -1) {
copyObj[key] = new String(objvalue);
}
if (objtype.indexOf("RegExp")) {
copyObj[key] = new RegExp(objvalue);
}
/***
* Math 是单体方法,静态方法.设计模式中的单利模型.只能直接调引用.
* 其实可以不用在这里单独列出来,下面也会处理:)
* */
if (objtype.indexOf("Math") > -1) {
copyObj[key] = obj[key];
}
/**递归调用
*
* copyObj(obj[key])
*
* 再或者
* arguments.callee(obj[key]);
*
**/
arguments.callee(obj[key]);
}
copyObj[key]=obj[key];
}
return copyObj;
}
var wanglinzhizhiskillstack = {
name: "wanglinzhizhi",
sayHello: function () {
console.log("hi , I'm " + this.name)
},
fullstack: {
ES6: {
JavaScrip: "80%",
ES6: "80%"
},
HTML: {
HTML5: '90%',
HTML: '80%'
},
CSS: {
CSS3: '90%',
CSS: '80%'
}
},
birthday: new Date("1991/02/08"),
emailFilter: new RegExp("/^(\w+[_|\.|\_]?)*(\w)+@(\w+[_|\.|\_])*(\w)+\.[a-zA-z]{2,4}$/","gi")
}
var wanglinzhizhiCopy = copyObj(wanglinzhizhiskillstack)
wanglinzhizhiCopy.birthday=new Date("2019/12/12")
wanglinzhizhiCopy.emailFilter=/\w$/gi;
console.log(wanglinzhizhiCopy.birthday)
console.log(wanglinzhizhiskillstack.birthday)
console.log(wanglinzhizhiskillstack.emailFilter);
console.log(wanglinzhizhiCopy.emailFilter);
})()

Notes : 有个需要留意地方是 ,对象的属性可能 也是引用类型的,需要判断下,若是引用类型,则需要递归调用 copyObj 方法.






way2 -> Object.create()

(() => {
function copyObj(obj) {
var copyObj = {};
for (let key of Object.keys(obj)) {
//引用类型
if (obj[key] instanceof Object) {
let toString = Object.prototype.toString;
let objtype = toString.call(obj[key])
let objvalue = obj[key].toString();
/***
*
* 对于几种特殊的 引用类型需要额外处理下,Date 类型, 正则类型等.
*
* Math 类型,不需要处理, 因为 Math 属于 global 类型的(属于设计模式中的单体模型).
*
* null undefined 类型可以不用处理,是因为,for...of 循环 可处理,不会像 forin,forEach 跳过.
*
* toString.call(new Date); // [object Date]
* toString.call(new String); // [object String]
* toString.call(Math); // [object Math] //Since JavaScript 1.8.5
* toString.call(undefined); // [object Undefined]
* toString.call(null); // [object Null]
*
*/
if (objtype.indexOf("Date") > -1) {
copyObj[key] = new Date(objvalue);
}
if (objtype.indexOf("String") > -1) {
copyObj[key] = new String(objvalue);
}
if (objtype.indexOf("RegExp")) {
copyObj[key] = new RegExp(objvalue);
}
/***
* Math 是单体方法,静态方法.只能直接调引用.
* 其实可以不用在这里单独列出来,下面也会处理:)
* */
if (objtype.indexOf("Math") > -1) {
copyObj[key] = obj[key];
}
/**递归调用
*
* copyObj(obj[key])
*
* 再或者
* arguments.callee(obj[key]);
*
**/
arguments.callee(obj[key]);
}
copyObj = Object.create(obj)
}
return copyObj;
}
var wanglinzhizhiskillstack = {
name: "wanglinzhizhi",
sayHello: function () {
console.log("hi , I'm " + this.name)
},
fullstack: {
ES6: {
JavaScrip: "80%",
ES6: "80%"
},
HTML: {
HTML5: '90%',
HTML: '80%'
},
CSS: {
CSS3: '90%',
CSS: '80%'
}
},
birthday: new Date("1991/02/08"),
emailFilter: new RegExp("/^(\w+[_|\.|\_]?)*(\w)+@(\w+[_|\.|\_])*(\w)+\.[a-zA-z]{2,4}$/","gi")
}
var wanglinzhizhiCopy = copyObj(wanglinzhizhiskillstack)
wanglinzhizhiCopy.birthday=new Date("2019/12/12")
wanglinzhizhiCopy.emailFilter=/\w$/gi;
console.log(wanglinzhizhiCopy.birthday)
console.log(wanglinzhizhiskillstack.birthday)
console.log(wanglinzhizhiskillstack.emailFilter);
console.log(wanglinzhizhiCopy.emailFilter);
})()






by wanglinzhizhi