js 深浅拷贝

一 了解深浅拷贝前提

1.es5 数据类型分为2种

1) 基本类型

Number,String,null,undefined,Boolean

2) 引用类型

Object

2堆栈保存

1)基本类型以键值对的形式是保存在栈中,键是变量标识符,值是变量值

栈内存 header 2
标识符 变量值
标识符 变量值

2)引用类型数据,对象实际内容是保存在堆中,栈内存中只保存变量标识符,值是引用地址(实际内容在堆中的位置)

二 深浅拷贝

1.var b= a ,实际上是复制了一份a 的栈内存

当a 是基础类型变量时, 这样是深拷贝。两者不会互相影响。

栈内存 header 2
a 5
b 5

而当a 是引用类型时,实际上只复制了对象a的引用地址,当a 改变时,b 也会受到影响。2个指向同份堆内存,互相影响。

1
2
3
4
var a={name:'a',age:20};
var b=a;
b.name='b';
console.log(a.name=='b'); //true
栈内存 header 2
a a 在堆中的位置
b a 在堆中的位置

2.深浅拷贝的基础实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/对所有属性进行遍历,如果是基本类型,直接copy .否则递归遍历属性的子属性知道基本类型。
function deepClone(obj){
var deepObj;
if(!obj||typeof obj!=='object'){
throw new Error('arguments error','error');
}
Array.isArray(obj)?deepObj=[]:deepObj={};
//obj.constructor==Array?deepObj=[]:deepObj={};
for(key in obj){
debugger;
if(obj.hasOwnProperty(key)){
if(obj[key]&&typeof obj[key]==='object'){
deepObj[key]=deepClone(obj[key]);
}
else{
deepObj[key]=obj[key];
}
}
}
return deepObj;
}

//测试
function test(){
var a=[1,2,{‘name’:’jiongrong’,age:20}];
var b=deepClone(a);
b[2].name=’jiongrong1’;
var c=[1,2,{people:{name:’yingfei’},age:20}];
var d=deepClone(c);
d[2].people.name=’yingfei1’;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
}

1
2
### 3.快速深拷贝的现成方法
1)常用 JSON.parse() .JSON.stringify()
var d=JSON.parse(JSON.stringify(c));
1
2
2) jquery 提供了extend 方法
function run3(){
  var a=[1,2,{'name':'jiongrong',age:20}];
  var b=$.extend(true,{},a);  //true 是深拷贝  false 浅拷贝 数组拷贝完类型会不一样
  b[2].name='jiongrong1';
  console.log(a);
  console.log(b);
  var c=[1,2,{'name':'jiongrong',age:20}];
  var d=$.extend(false,{},c);
  d[2].name='jiongrong1';
  console.log(c);
console.log(d);

}
```
image

写完,花时2个半小时 2017年9月12日