15/8/2 对象简单、深度克隆(复制)

参考:http://qianduanblog.com/post/js-learning-30-object-clone-copy.html

基本数据类型:Boolean/Number/String

 

var a='a';
var b;
b=a;
b='b';
console.log(a);
console.log(b);

 基本数据类型的克隆是对象的直接克隆,两者只是值得传递,克隆之后两者没有联系

引用数据类型:Array/Object/Function

数组的克隆

var a = [1,2];
var b;
b = a;
b[2] = 3;
console.log(a);    // {1,2,3}

  这种普通的克隆可以看到两者控制的是同一个对象,这是引用类型的特点。可以通过循环来克隆无关的两组数组。

var a = [1,2];
var b = [];
var i = 0;
var j = a.length;
for (;i<j;i++) {
  b[i] = a[i];            
}
b.push(3);
console.log(b);  // {1,2,3}
console.log(a);  // {1,2}

  

因为数组也是对象,所以的对象的克隆和数组是一样的

var a = {1:'one',2:'two'}
var b = {};
for(var i in a) {
    b[i] = a[i];
}
console.log(b);     // Object {1: "one", 2: "two"}
b[3] = 'three';
console.log(b);    // Object {1: "one", 2: "three"}
console.log(1);    // Object {1: "one", 2: "two"}

  

 函数的克隆比较特殊:函数的克隆,使用“=”符号就可以了,并且在改变克隆后的对象,不会影响克隆之前的对象,因为克隆之后的对象会单独复制一次并存储实际数据的,是真实的克隆。

var x=function(){alert(1);};
var y=x;
y=function(){alert(2);};

// function(){alert(1);};
alert(x);

// y=function(){alert(2);};
alert(y);

  

完整的对象克隆:

  完整的对象克隆需要对参数进行类型判断,是个综合的应用。

 

function isArray(arr) {
	return Object.prototype.toString.call(arr) === "[object Array]";
}
function isPlain(obj){
	return Object.prototype.toString.call(obj) === "[object Object]";
}
function cloneObject(src) {
	var result = src;
	if(!src
		|| src instanceof Number
		|| src instanceof String
		|| src instanceof Boolean) {
		return result;
	}else if(isArray(src)) {
		var result = [];
		var resultLen = 0;
		for(var i = 0,len = src.length;i < len; i++) {
			result[resultLen++] = cloneObject(src[i]);
		}
	}else if (isPlain(src)) {
		result = [];
		for (var i in src) {
			if (src.hasOwnProperty(i)) {
				result[i] = cloneObject(src[i]);
			}
		}
	}
	return result;
}
// 测试用例
var srcObj = {
    a: 1,
    b: {
        b1: ["hello", "hi"],
        b2: "JavaScript"
    }
};
var abObj = srcObj;
var tarObj = cloneObject(srcObj);

srcObj.a = 2;
srcObj.b.b1[0] = "Hello";

console.log(abObj.a);
console.log(abObj.b.b1[0]);

console.log(tarObj.a);      // 1
console.log(tarObj.b.b1[0]);    // "hello"

  

原文地址:https://www.cnblogs.com/Eyrum/p/4696684.html