Javascript對象賦值操作


首先,我們還是舉個例子來說明對象賦值操作的問題吧:
ps: 本文默認約定log = console.log

 function A(){}
 A.prototype.x = 10;
 var a1 = new A();
 A.prototype = {
 	x: 20,
 	y: 20
 };
 var a2 = new A();
log([a1.x, a1.y, a2.x, a2.y]); // [10, undefined, 20, 20]

js中對象賦值操作我們可以通過c語言中得指針概念來解釋。

對象的淺拷貝

直接通過賦值操作符“=”將變量a中的對象賦值給變量b,此時我們更改a、b其中一個,另一個也會隨之更改。

var a = [1, 1],
	b = a;
	b[0] = 2;
	log(a[0]); // 2

因為我們在將a的對象賦值給b時,js引擎內部的操作只是簡單的將a所指的對象的地址賦值給b,此時a與b指向內存中同一個對象,所以才會出現這種情況。這種賦值方式稱為對象的淺拷貝。
我們可以從另一個方面論證我們的觀點:

log(a === b); // true,毫無疑問

var c = [2, 1];
log(a === c); // false

出現這種情況的原因就是變量c指向的是另一個和變量a指向的對象的值相同的對象,僅僅只是兩個指向的對象的值相同,但兩個對象在內存的地址是不一樣的,所以是false。
另外,我們知道js數組中有一些方法可以實現數組的完全復制,即兩個變量分別指向兩個對象:

	b = a.concat([]),
    c = a.slice(0),
    d = a.splice(0, a.length);
	log(b === a); // false

但是我們要針對對象進行復制的話,只能手動進行模擬,即所謂的對象深拷貝。

對象的深拷貝

顧名思義,就是利用“=”對於基本類型的操作不存在上述問題,通過for-in深度遍歷對象的屬性,然后將其賦值給另一個新的對象。

function cloneObj(obj) {
	var tempObj = {};
	
	if (obj instanceof Array) {
		tempObj = [];
	}
	
	for (var prop in obj) {
		if (typeof prop === 'Object') {
			cloneObj(prop);
		}
		
		tempObj[prop] = obj[prop];
	}
	
	return tempObj;
}

var myCountry = {
	name: 'China',
	birth: 1949
},

country = cloneObj(myCountry);

log(country === myCountry); // false

結束語

最后,我們回到第一個例子,會發現,引擎內部對於new對象的原型鏈也是通過簡單的賦值操作的方式,即對象的淺拷貝。而ES5新增的Object.create()也是淺拷貝的一種封裝:

var myCountry = {
        name: 'China',
        birth: 1949
    },

    country = Object.create(myCountry);

console.log(country.__proto__ === myCountry); // true


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM