深度克隆和浅克隆整体的逻辑解说!

(function() { //匿名自执行函数第一种写法
	//浅克隆  
	var oPerson = {
		oName: "rookiebob",
		oAge: "18",
		oAddress: {
			province: "beijing"
		},
		ofavorite: [
			"swimming",
			{
				reading: "history book"
			}
		],
		skill: function() {
			console.log("bob is coding");
		}
	};

	function lowClone(obj) {
		var resultObj = {}
		for(key in obj) {
			resultObj[key] = obj[key]
		}
		return resultObj
	}

	//obj.assign({},obj2)只是简单的一层赋值浅赋值!如果改变深层的对象的就会把原来的改变
	//对象的赋值和对象之间是有联系的可以转换成字符,付完值之后在转回来
	var newClone = lowClone(oPerson)
	//console.log(oPerson.oAddress.province)
	newClone.oAddress.province = '上海'; //对象的赋值就
	//console.log(oPerson.oAddress.province)
})()

/*
 * 深度克隆的核心思想
 * 1,首先的写一个方法来判断一个对象的类型完全区分简单类型和复杂类型的
 * 2,通过判断的类型来创建对应的对象是数组还是对象
 * 3,每次对传进去的参数在进行遍历直到找到没有对象和数组
 * 4,利用递归argument.callee.()
 * 
 */
var oPerson = {
	oName: "rookiebob",
	oAge: "18",
	oAddress: {
		province: "beijing"
	},
	ofavorite: [
		"swimming",
		{
			reading: "history book"
		}
	],
	skill: function() {
		console.log("bob is coding");
	}
};

//首先写一个函数来判断对象的具体类型
function isClass(o) {
	if(o === 'null') return 'Null';
	if(0 === 'undefined') return 'Undefined'
	return Object.prototype.toString.call(o).slice(8, -1)
}
/*
 * 1,深度克隆主要利用的递归的原理和能够判断到底是对象还是数组
 * 2,是对象就返回定义一个空的对象中
 * arguments.callee(copy)本身返回当前的对象的只是调用了一下当前的函数
 * 当然也可以是当前的函数名称
 * */
function deepClone(obj) {
	var resultClone, oClass = isClass(obj)
	console.log()
	if(oClass.toLowerCase() == 'object') {
		resultClone = {}

	} else if(oClass.toLowerCase() == 'array') {
		resultClone = []
	} else {
		return obj
	}
	for(key in obj) {
		var copy = obj[key]
		if(isClass(copy).toLowerCase() === 'object') {
			resultClone[key] = arguments.callee(copy)
		} else if(isClass(copy).toLowerCase() === 'array') {
			resultClone[key] = arguments.callee(copy)
		} else {
			resultClone[key] = obj[key]
		}
	}
	return resultClone
}
var newClone = deepClone(oPerson)
//console.log(newClone)
			/*
			 * 自己手写深度克隆
			 * 直接调用系列过程语句间接过程
			 * 将所有的实在参数,返回地址等信息传递给被调用的过程保存;
			 * 为被调用过程的局部变量分配存储空间;
			 * */
	var isObject = (obj)=>{
		if(obj=='undefined') return 'undefined';
		if(obj=='null') return 'null';
		return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase()
 	}
	var deepCloneCope = function(objKey) {
		var copyObj;
		if(isObject(objKey) == 'object'){
			copyObj = {};
		}else if(isObject(objKey) == 'array'){
			copyObj = [];
		}else{
			return objKey
		}
		for(key in objKey){
			copyTwoKey = objKey[key];
			if(isObject(copyTwoKey)=='object'){//通过判断具体的类型来放入具体的类型当中
				//console.log(copyObj[key])//undefined说明运算的时候只是执行后面的程序
				//就是每一个对象只有执行到最后只剩一个value在么有对象和数组
				copyObj[key] = arguments.callee(copyTwoKey)
				console.log(arguments.callee(copyTwoKey))
				console.log(copyObj)
			}else if(isObject(copyTwoKey)=='array'){
				copyObj[key]= arguments.callee(copyTwoKey)
			}else{
				copyObj[key]=objKey[key]
			}
		}
		return copyObj
	}
	console.log(deepCloneCope(oPerson))
	
function foo(...args){//Es6的Rest参数
	//真正的数组,而arguments只是带有长度的类数组	
    //console.log(args);
}
foo(1, 2, 3);// [1, 2, 3]
					/*
					 * 递归的操作
					 * 那就说明递归的函数只会走条件其他的不会改变
					 * */
function countNum(num){
	var a = 1;
	console.log(a)
	if(num-1>0){
		console.log(a)
		a=  num*arguments.callee(num-1)
		//console.log(num*arguments.callee(num-1))
	}
	return a
}
//console.log(countNum(5))

猜你喜欢

转载自blog.csdn.net/wangyun_gogo/article/details/81671075