js的栈堆与浅拷贝、深拷贝的理解

一:什么是堆栈?

  咱们都知道:在计算机领域中,堆栈是两种数据结构,它们只能在一端(称为栈顶(top))对数据项进行插入和删除。javascript

  • 堆:队列优先,先进先出;由操做系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操做方式相似于数据结构中的栈。
  • 栈:先进后出;动态分配的空间 通常由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式却是相似于链表。 
    以上都属于计算机基础部分,在此都不详细赘述了,下面咱们联系JavaScript来剖析一下堆栈。
  • 栈堆之间的关系,在栈中存放的基本类型数据若是包含了应用类型(heap),那么栈中存放的只是堆中的一个地址,根据这个地址系统能够找到数据在堆中的位置。

二:JavaScript中的基本类型和引用类型与堆栈有什么联系?

JavaScript的数据类型分为两大种: 
1. 基本类型:Undefined、Null、Boolean、Number 和 String,这5中基本数据类型能够直接访问,他们是按照值进行分配的,存放在栈(stack)内存中的简单数据段,数据大小肯定,内存空间大小能够分配。 
2. 引用类型:即存放在堆(heap)内存中的对象,变量实际保存的是一个指针,这个指针指向另外一个位置。 
  以上咱们知道了什么是堆栈,和JavaScript的数据类型,下面咱们根据js的数据类型来讲明一下他们的拷贝状况:java

结合下面的例子理解堆栈的关系:程序员

var xm = {
		age: 18,
		score: 4
	};
	var xh = {
		age: 18,
		score: 4
	};
	console.log(xm===xh);   //false

var  newobj=xh
	console.log(newobj===xh);   //true


//下面这也是一个你叫经典的例子能够试一下

	function setName(obj) {
		obj.name = 'xm';  //在传参数中新建内存对象,而且设定一个值
		obj = {};          //对象是引用类型。系统在堆中新建一个内存空间,与传入值无关。
		obj.name = 'xh';   //在新建的内存空间设置一个值(与传入值是独立开来的。)
	}
	var person = {};
	setName(person);
	console.log(person.name);   // xm
//console.log([] instanceof Array);
// console.log(typeof []);

xm和xh的对象值是同样的,但是在关系比较重为false,当新建对象赋值是这种状况就是true.下图给你们讲解。数据结构

这就会出现另一种状况,咱们想去判断引用类型的值是否相等,(下面以对象为例子进行讲解。)函数

var xm = {
		age: 18,
		score: 4
	};
	var xh = {
		age: 18,
		score: 4
	};
function equalObjs(a, b) {
		for (var p in a) {
			if (a[p] !== b[p]) return false;
		}
		return true;
	}

三:什么是浅拷贝?

   基本类型拷贝的时候只是在内存中又开辟了新的空间,是的新建的值与拷贝值相互独立。(能够理解为在堆中新建一个空间存放一样的值。)这个方法能够利用上面判断相等的办法遍历出堆(heap)值从新赋值。所以深浅拷贝是相对于引用类型的。spa

var xm = {
		age: 18,
		score: 4,
		arr1:[1,32]
	};
	function copyObj(obj) {
		var newObj = {};
		for (var p in obj) {
			newObj[p] = obj[p];
		}
		return newObj;
	}
	var xh = copyObj(xm);
	// var arr1=[1,2,3]
	xh.arr1.push(33)
	console.log(xh)  //{age: 18, score: 4, arr1: Array(3)}
	console.log(xh===xm); //false
	console.log(xh.arr1===xm.arr1);  //true

console.log(xh.arr1===xm.arr1);  //true 这里出现了一个问题,浅拷贝中遍历对象里面包含了另一个应用类型(arr1),而它的空间是独立的,这样直接被引用。指针

若是想实现两个值的彻底独立,这时就须要使用到深拷贝。code

四:深度拷贝

      根据浅拷贝出现的问题,咱们可使用深拷贝的方法解决问题。对象

      深拷贝的方法比较多,我举一些比较简单的例子来讲明一下。blog

最简单的办法:JSON.parse(obj)

var xm = {
		age: 18,
		score: 4,
		arr1:[1,32]
	};
	var xh=JSON.parse(JSON.stringify(xm))
	xh.arr1.push(33)
	console.log(xh)  //{age: 18, score: 4, arr1: Array(3)}
	console.log(xh===xm); //false
	console.log(xh.arr1===xm.arr1);  //false

其余的方法须要使用递归操做来进行。

相关文章
相关标签/搜索