js有两种类型的值:
栈:原始数据类型(undefinen,null,boolead,number,string)
堆:引用数据类型(对象,函数和数组)
两种类型的区别是:储存位置不同,
原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小,大小固定,属于被频繁使用的数据,所以放入栈中存储;
引用数据类型存储在堆(heap)中的对象,占据空间大,大小不固定,如果存储在栈中,将会影响程序运行的性能,引用数据类型在栈中存储了指针,该指针指向堆中该尸体的起始地址。当解释器寻找引用值,会首先检索其在栈中的地址,取得地址后从堆中获取实体;
举个例子:
基本类型:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script> /*var a = 5;
var b = a;
b += 3;
alert(b); //8
alert(a); //5
*/ //对象和函数和数组都是引用的关系
/*var a = [1,2,3];
var b = a;
b.push(4);
alert(b); //1,2,3,4
alert(a); //1,2,3,4*/ var a = [1,2,3];
var b = a;
b = [1,2,3,4]; alert(b); //1,2,3,4
alert(a); //1,2,3
var obj={};
var objcopy=obj;
objcopy.fun=function(){
console.trace();
console.log('obi.fun');
};
obj.fun();//obi.fun同样会执行objcopy添加的fun方法,证明俩人是引用的同样的东东
</script>
</head> <body>
</body>
</html>
浅层拷贝:
function simpleClone(initalObj) {
var obj = {};
for ( var i in initalObj) {
obj[i] = initalObj[i];
}
return obj;
}
var obj = {
a: "hello",
b:{
a: "world",
b: 21
},
c:["Bob", "Tom", "Jenny"],
d:function() {
alert("hello world");
}
}
var cloneObj = simpleClone(obj);
console.log(cloneObj.b);
console.log(cloneObj.c);
console.log(cloneObj.d); cloneObj.b.a = "changed";
cloneObj.c = [1, 2, 3];
cloneObj.d = function() { alert("changed"); };
console.log(obj.b);//浅拷贝 改动一个对象的值,另一个还是会受到影响 浅拷贝其实就是简单的复制第一层,深层的改变依然会受影响
console.log(obj.c);
console.log(obj.d);
深拷贝:直接上个比较完善的方法,不会出问题的:(递归拷贝)
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : {};
deepClone(prop, obj[i]);
} else {
obj[i] = prop;
}
}
return obj;
}
var str = {};
var obj = { a: {a: "hello", b: 21} };
deepClone(obj, str);
obj.a=1;
console.log(str.a);//{a: "hello", b: 21} 互不影响
console.log(str.a.a)//hello
console.log(obj);//{a: 1}
使用Object.create()方法,也可以达到深层拷贝
直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
} else {
obj[i] = prop;
}
}
return obj;
}