js物件的幾種轉殖方式

2021-10-08 16:07:45 字數 2942 閱讀 2316

在js中物件轉殖就是把物件值重新賦給乙個新物件。轉殖也存在深轉殖於淺轉殖的區別。引用型別的值都會被儲存在堆記憶體中,在棧記憶體中會存在乙個指標指向堆記憶體中的值。這時,如果只複製了指標,則可以說這個轉殖為淺轉殖,如果時根據指標找到具體的值,複製值,就可以稱之為深轉殖。

1、json

json多用於前後臺的資料互動,後台傳遞字串型別的json資料,前端通過json.parse() ,可以轉化為乙個json物件。

現有乙個物件,可以通過json.stringify() 轉為json字串。字串型別的值儲存在棧記憶體當中,所以可以直接賦值達到深度轉殖的結果。最後通過json.parse(),就可以實現深度轉殖了。

var obj = 

};// 直接等於號賦值,如果是基本型別的資料,這樣足夠達到深度轉殖

var obj2 = obj;

console.log(obj2 == obj); //true 直接複製只是複製物件的指標,還指向同乙個物件

// 轉化為了字串

var obj3 = json.parse(json.stringify(obj));

console.log(obj3 == obj) //false 通過json方法複製後的位址不一樣

console.log(obj3); // 達到深度轉殖

不過這種方法不是萬能的,也是有缺陷的。

物件裡存在函式,無法轉殖。

var obj = ,

z: () =>

};var obj3 = json.parse(json.stringify(obj));

console.log(obj3); // } 不存在z這個函式

物件名如果是symbol型別的也是無法轉殖的。2、object.create()

object.create()用於把乙個物件用於另乙個物件的原型,這種以原型的方式來設定乙個物件在某個方面也算的上是一種轉殖,也可以間接的達到目的。但是不建議,某些方面來說算不上轉殖。

var obj = 

};var obj2 = object.create(obj);

console.log(obj2 == obj); //false

console.log(obj === obj2.__proto__); // true

console.log(obj2); // 輸出{}

因為只是把物件設定為新物件的原型,所以新物件不會和原來的物件相等,但是原物件會與新物件的原型相等。一般來說對轉殖出來的物件作修改,被轉殖的物件沒有被修改,就可以判定是乙個深轉殖出來的物件。但是要是去修改轉殖出來的物件的原型中的屬性,肯定會影響被轉殖的物件,這樣來看,又不像深轉殖。所以是不是深轉殖,界限不是很明確。不通過 _ _ proto_ _ 去訪問原型上的物件進行修改也不會改變被轉殖物件。

3、…運算子

都知道…運算子可以用於收集物件的所有屬性和陣列的所有值。

let arr = [1,2,3,4,5];

let arr2 = [...arr];

console.log(arr === arr2); // false

console.log(arr2); // [1, 2, 3, 4, 5]

轉殖出來的他倆不相等,那麼這就可以判定這樣是深轉殖了嗎。沒錯,這就可以這樣判定,但是物件就不一定了。

如果物件的屬性還是物件,那麼就會出現意外,物件的屬性都是基本型別的值的話,還是深度轉殖。

let obj1 = 

}let obj2 = ;

console.log(obj1 === obj2); // false

obj2.d.x = null; // 修改轉殖出來的物件的屬性d的屬性x

結果可以看到,obj1也被修改了。所以這不是深轉殖。

4、assign

assign為es7中的方法。方法用於將所有可列舉屬性的值從乙個或多個源物件複製到目標物件。它將返回目標物件。

這個方法就是乙個純淺轉殖。

let obj1 = 

}let obj2 = object.assign(obj1);

console.log(obj1 === obj2); // true

6、通用
function.prototype.clone = function(obj, newobj = {})

// 如果傳進來的是個空物件或者空陣列 則直接返回

if(!(obj == undefined || obj == null));

} else

// 遍歷傳進來的obj

for (const key in obj) else if (tostring.call(obj[key]) == "[object regexp]") else if (tostring.call(obj[key]) == "[object array]") else if (tostring.call(obj[key]) == "[object function]")

// 遞迴,當有陣列或者物件的時候繼續往裡面深入,重複呼叫當前的函式

function.clone(obj[key], newobj[key]);

} else }}

return newobj;

}let obj = ,

arr : [1,2,3,4,],

reg : new regexp('a'),

fun : function()

}

js物件的轉殖

由於js是採用引用傳值的,故修改任何乙個物件,其關聯的物件也會被改變,但很多時候我們只想得到乙個物件的拷貝,而非引用。下面提供了一種實現。不過除非程式中需要,否則要避免操作物件的拷貝,因為這樣會影響效能,造成太多的遞迴呼叫 too much recursive function clone o el...

js 建立物件的幾種方式

一 原始方式 解釋 原始方法建立物件,通過new關鍵字生成乙個物件,然後根據js是動態語言的特性新增屬性和方法,構造乙個物件。其中this是表示呼叫該方法的物件。缺點 多次建立物件,則需要重複 多次,不利於 的復用。二 工廠模式 var getage function var getname fun...

js 建立物件的幾種方式

第一種 工廠模式 例1 function createobj name,age return o var per1 createobj 張三 20 per1.sayinfo 缺點 無法知道物件的型別 第二種 建構函式模式 例2 function person name,age var per2 ne...