目录
深拷贝时首先要区分数组和对象(js中数组和对象都是Object类型,因此要做区分)
浅克隆和深克隆的实现
-
深浅克隆主要是为了区分引用类型和基本类型的克隆
深拷贝时首先要区分数组和对象(js中数组和对象都是Object类型,因此要做区分)
-
方法一:利用Object.prototype.toString.call()
var tem = "[object Array]";
// 区分对象和数组
function test() {
//首先判断是不是对象
if (typeof(arguments[0]) == "object") {
//在判断是不是数组
if (Object.prototype.toString.call(arguments[0]) == tem) {
console.log("数组");
} else {
console.log("对象");
}
} else {
console.log("不是对象");
}
}
-
方法二:利用instanceof
function test1() {
//利用instanceof
if (arguments[0] instanceof Array) {
console.log("数组");
} else {
console.log("对象");
}
}
浅拷贝实现
-
浅克隆直接将旧对象的地址复制给新对象,导致新对象值改变时,旧对象值也会跟着变
var obj = {
name: "abc",
age: 12,
cord: ["2", "3"],
}
var obj1 = {};
//浅拷贝
function clone(origin, target) {
var target = target || {};
for (var prop in origin) {
target[prop] = origin[prop];
}
}
-
浅拷贝后,obj中的cord为数组,数组在js中为引用类型,obj1 cord中的值改变后,obj接着也会变
深拷贝实现
法一:原生
- 深度克隆实现时,先创建一个新的空对象或者数组,再将要拷贝的对象的(值)赋给新的对象
- 深度克隆完之后不管是引用值还是基本值的改变都不会影响源对象
var obj = {
name: "abc",
age: 12,
cord: ["2", "3"],
}
var obj1 = {};
// 深度克隆完之后不管是引用值还是原始值的改变都不会影响源对象
// 先判断是不是原始值 typeof() object
// 判断是数组还是对象 instancof Object.prototype.toString.call constructor
// 建立相应的数组或对象
function deepClone(origin, target) {
var target = target || {},
//用来判断是数组还是对象
toStr = Object.prototype.toString,
//存放数组类型的String
arrStr = "[object Array]";
//遍历对象
for (var prop in origin) {
//只克隆对象的属性,不拿他原型链上的属性
if (origin.hasOwnProperty(prop)) {
// 判断当前是不是对象
if (origin[prop] !== "null" && typeof(origin[prop]) == "object") {
// 是数组建立一个空数组是对象建立一个空对象
target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {};
//再次克隆对象内部
deepClone(origin[prop], target[prop]);
} else {
target[prop] = origin[prop];
}
}
}
return target;
}
deepClone(obj, obj1);
-
深克隆之后就完全解决了这个问题,obj1中cord的内容改变之后,obj不会变
法二:JSON
var a = {name:122};
var b = JSON.parse(JSON.stringify(a));