咱们都知道:在计算机领域中,堆栈是两种数据结构,它们只能在一端(称为栈顶(top))对数据项进行插入和删除。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
其余的方法须要使用递归操做来进行。