国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【前端芝士樹】淺拷貝、深拷貝以及Object.assign()的作用、克隆對象、復制數(shù)組

ccj659 / 1711人閱讀

摘要:前端芝士樹淺拷貝深拷貝以及的作用首先還是得回到的基本數(shù)據(jù)類型。值類型深拷貝數(shù)值布爾值字符串。它接受任意數(shù)量的源對象,主要作用就是枚舉它們的所有屬性并分配給。

【前端芝士樹】淺拷貝、深拷貝以及Object.assign()的作用

首先還是得回到Javascript的基本數(shù)據(jù)類型。

值類型[深拷貝]:數(shù)值Num、布爾值Boolean、字符串String、null、undefined。

基本類型值是指在棧內(nèi)存保存的簡單數(shù)據(jù)段,在復制基本類型值的時候,會開辟出一個新的內(nèi)存空間,將值復制到新的內(nèi)存空間,舉個栗子:

var a = 1;
var b = a;
a = 2;
console.log(a);//輸出2;
console.log(b);//輸出1;
引用類型[淺拷貝]:對象、數(shù)組、函數(shù)等。

用類型值是保存在堆內(nèi)存中的對象,變量保存的只是指向該內(nèi)存的地址,在復制引用類型值的時候,其實只復制了指向該內(nèi)存的地址,舉個栗子:

var a={b:1}
var a2 = a;
a2.b = 2;
console.log(a)  // 輸出 {b: 2}

所以深拷貝問題的出現(xiàn)就是為了解決引用類型的數(shù)據(jù)的淺拷貝特性

實現(xiàn)對象深拷貝的幾種方法

JSON.parse() && JSON.stringfy()
將該對象轉(zhuǎn)換為其 JSON 字符串表示形式,然后將其解析回對象。這感覺有點太過簡單了,但它確實有效:

const obj = /* ... */;
const copy = JSON.parse(JSON.stringify(obj));

優(yōu)點是,如果沒有循環(huán)對象,并且不需要保留內(nèi)置類型,使用該方法皆可以獲得最快的跨瀏覽器的克隆性能。
這里的缺點是創(chuàng)建了一個臨時的,可能很大的字符串,只是為了把它重新放回解析器。
另一個缺點是這種方法不能處理循環(huán)對象,而且循環(huán)對象經(jīng)常發(fā)生。
例如,當我們構(gòu)建樹狀數(shù)據(jù)結(jié)構(gòu),其中一個節(jié)點引用其父級,而父級又引用其子級。

const x = {};
const y = {x};
x.y = y; // Cycle: x.y.x.y.x.y.x.y.x...
const copy = JSON.parse(JSON.stringify(x)); // throws!

另外,諸如 Map, Set, RegExp, Date, ArrayBuffer 和其他內(nèi)置類型在進行序列化時會丟失。

MessageChannel && postMessage 結(jié)構(gòu)化克隆算法
這種方法的缺點是它是異步的。雖然這并無大礙,但是有時候你需要使用同步的方式來深度拷貝一個對象。

function structuralClone(obj) {
  return new Promise(resolve => {
    const {port1, port2} = new MessageChannel();
    port2.onmessage = ev => resolve(ev.data);
    port1.postMessage(obj);
  });
}

const obj = /* ... */;
const clone = await structuralClone(obj);

Array.slice()Array.concat()方法屬于深拷貝嗎?

這個我都被弄糊涂了,網(wǎng)上找了些資料才捋清了一下。

對于一維數(shù)組而言

arrayObj.slice(start, [end])

var arr1 = ["1","2","3"];
var arr2 = arr1.slice(0);
arr2[1] = "9";
console.log("數(shù)組的原始值:" + arr1 ); //1,2,3
console.log("數(shù)組的新值:" + arr2 ); //1,9,3

arrayObj.concat(arr1,arr2 ... )

var arr1 = ["1","2","3"];
var arr2 = arr1.concat();
arr2[1] = "9";
console.log("數(shù)組的原始值:" + arr1 ); //1,2,3
console.log("數(shù)組的新值:" + arr2 );//1,9,3

那數(shù)組里面如果包含對象呢?

var arr1 = [{"name":"weifeng"},{"name":"boy"}];//原數(shù)組
var arr2 = [].concat(arr1);//拷貝數(shù)組
arr1[1].name="girl";
console.log(arr1);// [{"name":"weifeng"},{"name":"girl"}]
console.log(arr2);//[{"name":"weifeng"},{"name":"girl"}]

var a1=[["1","2","3"],"2","3"],a2;
a2=a1.slice(0);
a1[0][0]=0; //改變a1第一個元素中的第一個元素
console.log(a2[0][0]);  //影響到了a2

從上面兩個例子可以看出,由于數(shù)組內(nèi)部屬性值為引用對象,因此使用slice和concat對對象數(shù)組的拷貝,整個拷貝還是淺拷貝,拷貝之后數(shù)組各個值的指針還是指向相同的存儲地址。

Array.slice()Array.concat() 這兩個方法,僅適用于對不包含引用對象的一維數(shù)組的深拷貝!
Object.assign() 方法 以及 對象擴展操作符 ... Object.assign() 方法

Object.assign()考察點是ES6中實現(xiàn)對象復制,關(guān)于Object.assign()這個函數(shù)這里有一篇文章講得非常詳細明白。

ES6提供了Object.assign(),用于合并/復制對象的屬性。

Object.assign(target, source_1, ..., source_n)

下面是一個例子

var o1 = { a: 1, b: 1, c: 1 };
var o2 = { b: 2, c: 2 };
var o3 = { c: 3 };

var obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }

那么Object.assign()方法是淺拷貝還是深拷貝呢?請看下面這個例子:

function mutateDeepObject(obj) {
  obj.a.thing = true;
}

const obj = {a: {thing: false}};
const copy = Object.assign({}, obj);
mutateDeepObject(copy)
console.log(obj.a.thing); // prints true 
Object.assign(target, sources...)是一個簡單的拷貝對象的方式,屬于淺拷貝。它接受任意數(shù)量的源對象,主要作用就是枚舉它們的所有屬性并分配給target
對象擴展操作符 ...
使用對象擴展操作符 ...,對象自己的可枚舉屬性可以被拷貝到新對象。
const obj = { a: 1, b: 2, c:{d:"d"} }
const shallowClone = { ...obj }
shallowClone.a = "a";
shallowClone.c.d = "4";
console.log(obj); // a: 1, b: 2, c: {d: "4"}}
console.log(shallowClone); // a: "a", b: 2, c: {d: "4"}}
其他的看上去像是對象深拷貝,實質(zhì)是淺拷貝的方法
const obj = { a: 1, b: 2, c:{d:"d"} }
const shallowClone = Object.keys(obj).reduce((acc, key) => (acc[key] = obj[key], acc), {});
shallowClone.a = "a";
shallowClone.c.d = "4";
console.log(obj); // a: 1, b: 2, c: {d: "4"}}
console.log(shallowClone); // a: "a", b: 2, c: {d: "4"}}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/102812.html

相關(guān)文章

  • 拷貝拷貝

    摘要:二淺拷貝與深拷貝深拷貝和淺拷貝是只針對和這樣的引用數(shù)據(jù)類型的。淺拷貝是按位拷貝對象,它會創(chuàng)建一個新對象,這個對象有著原始對象屬性值的一份精確拷貝。對于字符串數(shù)字及布爾值來說不是或者對象,會拷貝這些值到新的數(shù)組里。 一、數(shù)據(jù)類型 數(shù)據(jù)分為基本數(shù)據(jù)類型(String, Number, Boolean, Null, Undefined,Symbol)和對象數(shù)據(jù)類型。 基本數(shù)據(jù)類型的特點:直...

    hzc 評論0 收藏0
  • 拷貝拷貝

    摘要:二淺拷貝與深拷貝深拷貝和淺拷貝是只針對和這樣的引用數(shù)據(jù)類型的。淺拷貝是按位拷貝對象,它會創(chuàng)建一個新對象,這個對象有著原始對象屬性值的一份精確拷貝。對于字符串數(shù)字及布爾值來說不是或者對象,會拷貝這些值到新的數(shù)組里。 一、數(shù)據(jù)類型 數(shù)據(jù)分為基本數(shù)據(jù)類型(String, Number, Boolean, Null, Undefined,Symbol)和對象數(shù)據(jù)類型。 基本數(shù)據(jù)類型的特點:直...

    史占廣 評論0 收藏0
  • JS拷貝

    摘要:引用類型之所以會出現(xiàn)深淺拷貝的問題,實質(zhì)上是由于對基本類型和引用類型的處理不同。另外方法可以視為數(shù)組對象的淺拷貝。上面描述過的復雜問題依然存在,可以說是最簡陋但是日常工作夠用的深拷貝方式。 一直想梳理下工作中經(jīng)常會用到的深拷貝的內(nèi)容,然而遍覽了許多的文章,卻發(fā)現(xiàn)對深拷貝并沒有一個通用的完美實現(xiàn)方式。因為對深拷貝的定義不同,實現(xiàn)時的edge case過多,在深拷貝的時候會出現(xiàn)循環(huán)引用等問...

    xiaoxiaozi 評論0 收藏0
  • ES6時代,你真克隆對象嗎?

    摘要:原文你真的會克隆對象嗎開始之前在開始聊克隆之前,我們還是先來看看數(shù)據(jù)類型。值通過函數(shù)生成,是獨一無二的。同時,中規(guī)定了對象的屬性名有兩種類型,一種是字符串,另一種就是類型。返回一個數(shù)組,包含對象自身的所有屬性的鍵名。 原文:你真的會克隆對象嗎 開始之前 在開始聊克隆之前,我們還是先來看看js數(shù)據(jù)類型。js的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和復雜數(shù)據(jù)類型。 基本數(shù)據(jù)類型:Number、Bool...

    xiaokai 評論0 收藏0
  • 拷貝拷貝區(qū)別

    摘要:淺拷貝與深拷貝一數(shù)據(jù)類型數(shù)據(jù)分為基本數(shù)據(jù)類型,和對象數(shù)據(jù)類型。淺拷貝是按位拷貝對象,它會創(chuàng)建一個新對象,這個對象有著原始對象屬性值的一份精確拷貝。對于字符串數(shù)字及布爾值來說不是或者對象,會拷貝這些值到新的數(shù)組里。 淺拷貝與深拷貝 一、數(shù)據(jù)類型數(shù)據(jù)分為基本數(shù)據(jù)類型(String, Number, Boolean, Null, Undefined,Symbol)和對象數(shù)據(jù)類型。 基本數(shù)據(jù)類...

    jsyzchen 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<