原始值和引用值
javaScripyou两种类型的值
stack 栈:原始数据类型(Undefined,Null,Boolean,Number、String)
因为原始值占据空间固定,是简单的数据段,为了便于提升变量查询速度,将其存储在栈(stack)中,栈内存之间的赋值是拷贝,只是一个副本,改变互不影响.
heap 堆:引用数据类型(Array, Oject, function....date ,RegExp)
由于复杂值的大小会改变,所以不能将其存放在栈中,否则会降低变量查询速度,因此其存储在堆(heap)中,存储在变量处的值是一个指针,指向存储对象的内存处 引用值之间的拷贝是地址.
原始值是不可以被改变的,var a = 10; a = 5;改变的是:重新建立一个存储区域,原来的值依然存在,只是地址 和 值之间的链接断了.
原始值和引用值引发的问题
1. 拷贝问题
浅层拷贝
function shallowCopy(Target, Origin){
for(var prop in Origin){
Target[prop] = Origin[prop]
}
return Target;
}
var obj = {
"name" : "ATM",
"card" : [1,1,1,2,5,2]
}
var obj1 = {};
shallowCopy(obj1, obj);
console.log(obj);// {"name" : "ATM","card" : [1,1,1,2,5,2]}
obj1.card.push(7);
console.log(obj1);// {"name" : "ATM","card" : [1,1,1,2,5,2,7]}
console.log(obj);// {"name" : "ATM","card" : [1,1,1,2,5,2,7]}
~显然这不是我们想要的结果,如果对obj1对象进行改变,obj也会随着改变.
上面代码就是一个浅层拷贝,将对象obj的值拷贝到对象'obj1'中,但是'obj'中有一个是属性'card'是一个引用值,引用值的 值 是存放到堆(heap)中的,obj1 拷贝的只是引用值在 栈 中的 ** 地址**,就会出现以下情况:
var father = [1, 3 , 5];
var son = [];
son = father;
console.log(son); // [1, 3, 5]
son.push(8);
console.log(son); //[1, 3, 5, 8]
console.log(father); //[1, 3, 5, 8]
son = [1,5];//son在堆中开辟了一个新的房间.
console.log(son); //[1, 5]
console.log(father) //[1, 3, 5, 8]
深度拷贝
function deepCopy(Target, Origin){
var Target = Target || {},
toStr = Object.prototype.toString,
str = "[object Array]";
for(var prop in Origin){
if(Origin.hasOwnProperty(prop)){
if (typeof(Origin[prop]) !== null && typeof(Origin[prop]) =="object") {
if(toStr.call(Origin[prop]) == str){
Target[prop] = [];
}else{
Target[prop] = {};
}
deepCopy(Target[prop], Origin[prop]);
}else{
Target[prop] = Origin[prop];
}
}
}
return Target;
}
var obj = {
"name" : "fanwenbo",
"card" : [1,2,3,4,5]
};
var obj1 = {};
deepCopy(obj1,obj);