深浅拷贝的理解

深浅拷贝对于一个从前的我来说,太陌生了,于是乎,面试又是一场惨败。其实还是很好理解的,深浅拷贝的原因,怎么写深浅拷贝的方法,还是挺简单的。
Js的数据类型:

  • 基本数据类型:null,undefined,数值类型,字符串类型,布尔类型
  • 引用数据类型:对象类型(数组,日期,正则表达式,函数)
    基本类型保存在栈内存中,引用类型值保存在堆内存中,指针保存在栈内存。这是因为栈内存只能存大小固定的数据,而引用类型的值大小是不固定的。
  1. 基本类型的值复制,然后修改是互不影响的。
var a=10;
var b=a;
b=20;
a; // 10
  1. 引用类型的值复制的只是地址指针,而值是同一个堆内存的数据,所以修改属性值时会互为影响,这就有了深浅拷贝的出现。
    让写一个浅拷贝方法的时候,我总是认为和基本类型值一样复制也是一种,然而实际是不同的。
var a={x:10,y:20};
var b=a;
b === a;//true
var c = {...a};
c === a;//false

浅拷贝方法
用Es6的展开运算符,可以简单快速的拷贝,如上一个demo。
for...in传统方法,注意不要复制到原型上去。

var obj = {a:123,b:[1,2,3]};
function simpleClone(obj){
  var temp={};
  for(let i in obj){
    if(obj.hasOwnProperty(i)){
      temp.i = obj.i;
    }
  }
  return temp;
}
simpleClone(obj);
//{i:undefined}

怎么错了呢,不是我想要的结果呢,哪里写的不对吗。原来还是基础不牢固,for...in遍历返回的是字符串类型,所以不能用obj.i,应是obj[i]。

var obj = {a:123,b:[1,2,3]};
function simpleClone(obj){
  var temp={};
  for(let i in obj){
    if(obj.hasOwnProperty(i)){
      temp[i] = obj[i];
    }
  }
  return temp;
}
simpleClone(obj);
//{a:123,b:[123]}

深拷贝方法
深拷贝简单粗暴的用递归,一层层的执行下去。

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 instanceof Array) ? [] : {};
            arguments.callee(prop, obj[i]);
        } else {
            obj[i] = prop;
        }
    }
    return obj;
}

这是网上找的一段代码,中间避免死循环的出现,一直没理解,相互引用怎么才能出现呢?

你可能感兴趣的:(深浅拷贝的理解)