js中值的基本类型与引用类型,以及对象引用,对象的浅拷贝与深拷贝

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;
}

 

posted @ 2019-01-01 22:34  古墩古墩  Views(432)  Comments(0Edit  收藏  举报