javascript.basics
javascript.basics copied to clipboard
浅复制与深复制(克隆)
JS复制
JS中对象,数组,函数都是通过引用传递的,因此如果只是单纯的赋值,仅仅是将对象的地址 进行引用,并不是正真的复制。需要一个一个进行处理。
浅度复制(改变原始对象值对新对象有影响)
// 对象要求:属性中有对象,且该内部对象有简单类型。
var person = {
name: "Bob",
sing:{
"name":"发如雪"
}
};
进行浅复制
function clone(object) {
var finalObject = {};
for (var i in object) {
finalObject[i] = object[i];
}
return finalObject;
}
var x =clone(person);
person.sing.text = "";
console.log(x);
- text的值被覆盖掉了,所以浅复制引用了同一份
如图,当原对象的text被改变之后,克隆出来的对象也被改变了,说明只是进行了浅度复制。
深度复制函数
// 用递归方法拷贝深层次对象
function clone3(cont) {
//这里增加了数组处理,暂时还不清楚函数体如何进行复制。
var object = (cont instanceof Array) ? [] : {};
for (var i in cont) {
// 如果是一个引用对象
if (cont[i] instanceof Object === true) {
// 要用object[i] = agruments.callee
// 代替object[i] = clone3(cont[i]);
object[i] = arguments.callee(cont[i]);
// 如果是一个简单对象,则直接赋值
} else {
object[i] = cont[i];
}
}
return object;
}
- 同样执行上述代码
// 对象要求:属性中有对象,且该内部对象有简单类型。
var person = {
name: "Bob",
sing:{
"name":"发如雪"
}
};
var x =clone3(person);
person.sing.text = "";
console.log(x);
- text值并没有被改变
用arguments.callee与直接使用函数名的区别,可以防止此类错误。
function people() {
console.log(111);
people();
};
var anoPeople = people;
people = null;
anoPeople();// Uncaught TypeError: people is not a function
【模仿函数递归调用】时的层级,是从最里面开始生成,最终生成a对象
//函数递归调用的特点
var a = function() {
return {"a":(function(){
return {"b": (function() {
return {"c":(function(){
return "myValue";
})()};
})()
};
})()
};
};
console.log(a());

补充下傻瓜递归
// 傻瓜式递归
if(b instanceof Object === true) {
for(var i in b) {
obj[i] = b[i];
if(b[i] instanceof Object === true) {
for(var j in b[i]) {
obj[i][j] = b[i][j];
if(b[i][j] instanceof Object === true) {
for(var m in b[i][j]) {
obj[i][j][m] = b[i][j][m];
}
}
}
}
}
}
别人博客借鉴,方法类似
function clone2(obj) {
var o,i,j,k;
// 是不是简单值
if (typeof(obj)!="object" || obj===null) {
return obj;
}
//是不是数组
if(obj instanceof(Array)){
o=[];
i=0;j=obj.length;
for(;i<j;i++){
if (typeof(obj[i])=="object" && obj[i]!=null) {
o[i]=arguments.callee(obj[i]);
}
else {
o[i]=obj[i];
}
}
//是不是对象
} else {
o={};
for(i in obj) {
if (typeof(obj[i])=="object" && obj[i]!=null) {
o[i]=arguments.callee(obj[i]);
} else {
o[i]=obj[i];
}
}
}
return o;
}
优化了网友的写法
- 1.实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制
function clone(total) {
var res = null;
var flag = function() {
return typeof(total) != "object" || total === null;
};
// 是不是简单类型
if (flag(total)) {
return total;
}
// 引用类型区分对象/数组
if (total instanceof Object) {
res = {};
for (var i in total) {
if (flag(total[i])) {
return arguments.callee(total[i]);
} else {
res[i] = total[i];
}
}
} else if (total instanceof Array) {
res = [];
for (var j = 0; j < total.length; j++) {
if (flag(total[j])) {
return arguments.callee(total[j]);
} else {
res[j] = total[j];
}
}
}
return res;
}
使用while处理的方法
/**
* 克隆一个对象
* @param Obj
* @returns
*/
function clone(Obj) {
var buf;
if (Obj instanceof Array) {
buf = []; //创建一个空的数组
var i = Obj.length;
while (i--) {
buf[i] = clone(Obj[i]);
}
return buf;
} else if (Obj instanceof Object) {
buf = {}; //创建一个空对象
for (var k in Obj) { //为这个对象添加新的属性
buf[k] = clone(Obj[k]);
}
return buf;
} else { //普通变量直接赋值
return Obj;
}
}
通过内部函数进行功能区分
function clone(total) {
var container;
// 判断是否是引用对象
function _flag(total) {
if (typeof total === "object") {
return true;
} else {
return false;
}
}
// 区分数组与对象并进行处理
function _referType(total) {
if (total instanceof Array) {
container = new Array();
for (var i = 0; i < total.length; i++) {
if (_flag(total) === false) {
container.push(total[i]);
} else {
container.push(_referType.caller(total[i]));
}
}
return container;
} else if (total instanceof Object) {
container = new Object();
for (var i in total) {
if (_flag(total) === false) {
container[i] = total[i];
} else {
container[i] = _referType.caller(total[i]);
}
}
return container;
}
}
//引用对象
if (_flag(total)) {
return _referType(total);
} else {
return total;
}
}