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

其餘的方法須要使用遞歸操做來進行。

相關文章
相關標籤/搜索