成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

js淺拷貝與深拷貝方法

lewif / 1387人閱讀

摘要:淺拷貝實(shí)現(xiàn)方式賦值。但是進(jìn)行的是淺拷貝,拷貝的是對象的屬性的引用,而不是對象本身。沒復(fù)制遞歸拷貝避免相互引用對象導(dǎo)致死循環(huán),如的情況使用方法直接使用,可以達(dá)到深拷貝的效果。

js有五種基本數(shù)據(jù)類型,string,number,boolean,null,undefind。這五種類型的賦值,就是值傳遞。特殊類型對象的賦值是將對象地址的引用賦值。這時候修改對象中的屬性或者值,會導(dǎo)致所有引用這個對象的值改變。如果想要真的復(fù)制一個新的對象,而不是復(fù)制對象的引用,就要用到對象的深拷貝。

淺拷貝實(shí)現(xiàn)方式 1.‘=’賦值。

不多說,最基礎(chǔ)的賦值方式,只是將對象的引用賦值。

2.Object.assign()

Object.assign是ES6的新函數(shù)。Object.assign() 方法可以把任意多個的源對象自身的可枚舉屬性拷貝給目標(biāo)對象,然后返回目標(biāo)對象。但是 Object.assign() 進(jìn)行的是淺拷貝,拷貝的是對象的屬性的引用,而不是對象本身。

Object.assign(target, ...sources)

參數(shù):
target:目標(biāo)對象。
sources:任意多個源對象。
返回值:目標(biāo)對象會被返回。

var obj = { a: {a: "hello", b: 21} };
var initalObj = Object.assign({}, obj);

initalObj.a.a = "changed";
console.log(obj.a.a); // "changed"

需要注意的是:
Object.assign()可以處理一層的深度拷貝,如下:

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = Object.assign({}, obj1);
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }
深拷貝 1.手動復(fù)制
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }
2.JSON做字符串轉(zhuǎn)換

用JSON.stringify把對象轉(zhuǎn)成字符串,再用JSON.parse把字符串轉(zhuǎn)成新的對象。

var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1);
// { body: { a: 10 } } <-- 沒被改到
console.log(obj2);
// { body: { a: 20 } }
console.log(obj1 === obj2);
// false
console.log(obj1.body === obj2.body);
// false

這樣做是真正的Deep Copy,這種方法簡單易用。

但是這種方法也有不少壞處,譬如它會拋棄對象的constructor。也就是深拷貝之后,不管這個對象原來的構(gòu)造函數(shù)是什么,在深拷貝之后都會變成Object。

這種方法能正確處理的對象只有 Number, String, Boolean, Array, 扁平對象,即那些能夠被 json 直接表示的數(shù)據(jù)結(jié)構(gòu)。RegExp對象是無法通過這種方式深拷貝。

也就是說,只有可以轉(zhuǎn)成JSON格式的對象才可以這樣用,像function沒辦法轉(zhuǎn)成JSON。

var obj1 = { fun: function(){ console.log(123) } };
var obj2 = JSON.parse(JSON.stringify(obj1));
console.log(typeof obj1.fun);
// "function"
console.log(typeof obj2.fun);
// "undefined" <-- 沒復(fù)制
3.遞歸拷貝
function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];        // 避免相互引用對象導(dǎo)致死循環(huán),如initalObj.a = initalObj的情況
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === "object") {
      obj[i] = (prop.constructor === Array) ? [] : {};            
      arguments.callee(prop, obj[i]);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}
var str = {};
var obj = { a: {a: "hello", b: 21} };
deepClone(obj, str);
console.log(str.a);
4.使用Object.create()方法

直接使用var newObj = Object.create(oldObj),可以達(dá)到深拷貝的效果。

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];        // 避免相互引用對象導(dǎo)致死循環(huán),如initalObj.a = initalObj的情況
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === "object") {
      obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}
5.jquery

jquery 有提供一個$.extend可以用來做 Deep Copy。

var $ = require("jquery");
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f);
// false
6.第三方函數(shù)

還有一些其它的第三方函數(shù)庫有深拷貝function,如lodash。

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/97883.html

相關(guān)文章

  • 關(guān)于js拷貝與深拷貝

    摘要:原文地址淺拷貝和深拷貝只針對像這樣的復(fù)雜對象的簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。淺拷貝通過來實(shí)現(xiàn)淺拷貝。 原文地址:http://www.silenceboy.com/201... 淺拷貝和深拷貝只針對像Object, Array這樣的復(fù)雜對象的.簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。 淺拷貝 通過 Object.ass...

    summerpxy 評論0 收藏0
  • JavaScript中的拷貝與深拷貝

    摘要:所以,深拷貝是對對象以及對象的所有子對象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對于深拷貝的對象,改變源對象不會對得到的對象有影響。 為什么會有淺拷貝與深拷貝什么是淺拷貝與深拷貝如何實(shí)現(xiàn)淺拷貝與深拷貝好了,問題出來了,那么下面就讓我們帶著這幾個問題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯誤之處,還請看到的小伙伴多多指教,先行謝過 以下↓ 數(shù)據(jù)類型在開始了解 淺拷貝 與 深拷貝 之前,讓我們先...

    546669204 評論0 收藏0
  • JavaScript中的拷貝與深拷貝

    摘要:所以,深拷貝是對對象以及對象的所有子對象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對于深拷貝的對象,改變源對象不會對得到的對象有影響。 上一篇 JavaScript中的繼承 前言 文章開始之前,讓我們先思考一下這幾個問題: 為什么會有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實(shí)現(xiàn)淺拷貝與深拷貝 好了,問題出來了,那么下面就讓我們帶著這幾個問題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯誤之處...

    AZmake 評論0 收藏0
  • 20170606-拷貝與深拷貝

    摘要:什么是深拷貝,什么是淺拷貝中的淺拷貝與深拷貝是針對復(fù)雜數(shù)據(jù)類型引用類型的復(fù)制問題。 什么是深拷貝,什么是淺拷貝 JS中的淺拷貝與深拷貝是針對復(fù)雜數(shù)據(jù)類型(引用類型)的復(fù)制問題。 淺拷貝:淺拷貝是拷貝引用(拷貝地址),拷貝后兩個變量指向的是同一塊內(nèi)存空間 深拷貝:會在內(nèi)存中開辟一塊新的內(nèi)存空間,它不僅將原對象的各個屬性逐個復(fù)制過去,而且將原對象各個屬性所包含的內(nèi)容也依次采用深復(fù)制的方法...

    Kerr1Gan 評論0 收藏0
  • 小tips:JS拷貝與深拷貝

    摘要:淺拷貝深拷貝淺拷貝的問題如果父對象的屬性等于數(shù)組或另一個對象,那么實(shí)際上,子對象獲得的只是一個內(nèi)存地址,而不是真正拷貝,因此存在父對象被篡改的可能。 淺拷貝: function extendCopy(p) {  var c = {};  for (var i in p) {    c[i] = p[i];  }  return c; } 深拷貝: function deepCopy(p...

    Soarkey 評論0 收藏0

發(fā)表評論

0條評論

lewif

|高級講師

TA的文章

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