js 值类型的存储形式--值类型以栈(后进先出)的形式存储;引用类型以栈和堆相结合的形式存储
代码演示
/* 值类型在栈中存储的value是值,b复制了a,只是拷贝了a的值,b重新赋值对a没有影响 */
var a = 'hello';
var b = a;
b = 'world'
console.log(a,b);//hello world
/**
* 引用类型的值存储在堆中,栈的value存储内存地址--指向属性值在堆中的物理位置
* 所以此处b拷贝的是a在栈中存储的内存地址
* 当b 对该属性重新赋值,即是对该内存地址指向的值重新赋值
* 这就是浅拷贝
*/
var obj1 = {'age' : 10};
var obj2 = obj1;
obj2.age = 20;
console.log(obj1.age);//20
浅拷贝--B赋值了A,当A的值发生改变时,B也跟着改变
浅拷贝的几种方式
1、遍历赋值
var obj ={
a : 'javascript',
b : {
x : 'world',
y : 111
},
c : [1,2,3]
}
function simpleClone (obj1) {
var obj2 = {},
for(var i in obj1) {
obj2[i] = obj1[i]
}
return obj2;
}
var objCopy = simpleClone(obj);
objCopy.b.x = 'worldCopy'
console.log(obj); //obj.b.x = 'worldCopy'
console.log(objCopy);
2、Object.creat()--能拷贝到该对象的原型链上的__proto__属性
var obj ={
a : 'javascript',
b : {
x : 'world',
y : 111
},
c : [1,2,3]
}
var objCopy = Object.create(obj);
objCopy.b.x = 'worldCopy'
console.log(obj); //obj.b.x ==> 'worldCopy'
console.log(objCopy);
深拷贝(工作中主要拷贝方式)--B拷贝了A,当A的值发生改变时,B不发生改变
1、遍历深拷贝
// 手写深拷贝
function deepClone(startObj,endObj) {
if(typeof startObj!= 'object' || startObj === null) {
return obj = startObj
}
var obj = endObj || {}
for(var key in startObj) {
// 判断key是否startObj 上的属性,不包含原型链
if(startObj.hasOwnProperty(key)) {
if(typeof startObj[key] !=='object' || startObj[key] === null){
obj[key] = startObj[key]
}else{
obj[key] = startObj[key].constructor === Array? []: {}
deepClone(startObj[key],obj[key])
}
}
}
return obj
}
var objCopy = deepClone(obj);
objCopy.b.x = 'worldCopy'
console.log(obj); //obj.b.x ==> 'world'
console.log(objCopy);
2、Object.create()做深拷贝--不常用,一般常见于做浅拷贝
//判断startObj的key为数组或对象,不为null
if(typeof startObj[i] !== 'object' || startObj[i] == null) {
obj[i] = startObj[i];
}else{
//原理同上,只是通过Object.create()创建一个空对象
obj[i] = startObj[i].constructor ===Array? [] : Object.create({})
//回调函数,处理对象中还有引用类型的情况--深度拷贝
deepClone(startObj[i], obj[i]);
}
3、JSON.parse()--工作中比较常见
var objCopy = JSON.parse(JSON.stringify(obj)) //object-->string-->object