賦值、淺拷貝和深拷貝

三種方法的形式存在必定的相似,可是也存在各個之間不相同的地方。javascript

淺拷貝和深拷貝是用在對象(Object)或者數組(Array)這樣的數據類型拷貝賦值時候的說法,而賦值操做也能夠用在基礎的數據類型,如Number、String等;java

賦值(對於對象類型數據的影響):賦於該值在棧中的地址,而不是堆中的數據,使得兩個對象同時指向到同一個存儲的空間,若是有某一個對象改變,其實都是改變存儲空間的內容,從而對兩個對象都產生相同的影響;

var aa = [ 1, 2, 3 ],bb;
bb = aa;
console.log(aa, bb); // aa = [1,2,3], bb = [1,2,3];
bb.push(5);//這裏操做的是aa、bb指向的存儲空間,因此aa、bb的值都發生了變化
console.log(aa, bb); // aa = [1,2,3,5], bb = [1,2,3,5];
bb[0] = 10;//這裏操做的是aa、bb指向的存儲空間,因此aa也發生了變化
console.log(aa, bb); // aa = [10,2,3,5], bb = [10,2,3,5];
bb = [ 2, 3, 4 ];//這裏已經把bb指向了另外一個數組,因此不會影響aa的值
console.log(aa, bb); // aa = [1,2,3,5], bb = [2,3,4];

淺拷貝(按位拷貝對象,若是是基本數據類型,就拷貝這個類型的值,若是是內存對象,則拷貝這個內存地址,因此淺拷貝介於賦值與深拷貝之間,淺拷貝過來的對象,可能存在改變某一個屬性的值會影響另外一個對象,也可能不影響)

ps:該淺拷貝的方法會覆蓋原對象中相同屬性的值,不需覆蓋能夠進行判斷數組

//淺拷貝的方法
var extend = function(to, from) {
	for (var property in from) {
        //if(to.hasOwnProperty(property)) continue; //不須要覆蓋能夠執行該方法
        if(!from.hasOwnProperty(property)) continue;
        Object.defineProperty(to,property,Object.getOwnPropertyDescriptor(from,property));
	}
	return to;
};

var aa = { name: 'ou', language: [ 'chinese' ] };
var bb = {};

bb = extend(bb, aa);
console.log('aa---', aa, 'bb---', bb);
bb.name = 'ming';
bb.language[0] = 'english';
console.log('aa---', aa, 'bb---', bb);

深拷貝,相對於淺拷貝,就是把對於引用內容地址的對象,新開闢一塊新的內存地址用於存放拷貝過來的內容,從而使得兩個對象不會再相互影響

ps:深拷貝涉及到比較複雜的數據類型的判斷,性能優化

可遍歷的:Object、Array 、Map、Set函數

不可遍歷的:Bool、Number、String、Date、Error等性能

還有正則、克隆函數等優化

//簡單對對象類型進行判斷
var extend = function(to, from) {
	for (var property in from) {
		if (typeof from[property] === 'object') {
			let cloneTarget = Array.isArray(from[property]) ? [] : {}; //進行判斷,屬性的值是對象仍是數組
			for (var key in from[property]) {
				cloneTarget[key] = from[property][key];
			}
			to[property] = cloneTarget;
		} else {
			Object.defineProperty(to, property, Object.getOwnPropertyDescriptor(from, property));
		}
	}
	return to;
};
...未完待續(後面可能補充有關對於類型的判斷,還有一些其它大神看到的性能優化、循環引用的問題)
相關文章
相關標籤/搜索