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

資訊專欄INFORMATION COLUMN

對(duì)象的合并及拷貝

econi / 2449人閱讀

摘要:方法用于對(duì)象的合并,將所有自身的非繼承的可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象拷貝到目標(biāo)對(duì)象。比如,如果對(duì)象的屬性是函數(shù)或?qū)ο?,該屬性?huì)被過濾掉,導(dǎo)致拷貝時(shí)會(huì)缺少屬性。利用遞歸對(duì)每一層都重新創(chuàng)建對(duì)象并賦值從而實(shí)現(xiàn)深拷貝

Object.assign()

Object.assign() 方法用于對(duì)象的合并,將所有自身的(非繼承的)可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象拷貝到目標(biāo)對(duì)象。返回目標(biāo)對(duì)象。目標(biāo)對(duì)象自身也會(huì)改變。

Object.assign(target, ...sources)

target: 目標(biāo)對(duì)象。

sources: 源對(duì)象。

Object.assign() 合并拷貝屬性的限制

只拷貝源對(duì)象的自身屬性(不拷貝繼承屬性),也不拷貝不可枚舉的屬性(enumerable: false)。

Object.assign({b: "c"},
  Object.defineProperty({}, "invisible", {
    enumerable: false,
    value: "hello"
  })
)
// { b: "c" }
參數(shù)類型 1. 只有一個(gè)參數(shù)

如果只有一個(gè)參數(shù),Object.assign() 會(huì)直接返回該參數(shù)。

let obj = {a: 1};
Object.assign(obj) === obj // true

如果該參數(shù)不是對(duì)象,則會(huì)先轉(zhuǎn)成對(duì)象,然后返回。

typeof Object.assign(2) // "object"

由于 undefinednull 無法轉(zhuǎn)成對(duì)象,所以如果它們作為參數(shù),就會(huì)報(bào)錯(cuò)。

Object.assign(undefined) // 報(bào)錯(cuò)
Object.assign(null)      // 報(bào)錯(cuò)
2. 對(duì)象 + 非對(duì)象

非對(duì)象參數(shù)都會(huì)轉(zhuǎn)成對(duì)象,如果無法轉(zhuǎn)成對(duì)象,就會(huì)跳過,不會(huì)報(bào)錯(cuò)。

如果非對(duì)象參數(shù)為 undefinednull ,就會(huì)跳過,不會(huì)報(bào)錯(cuò),返回的依舊是目標(biāo)對(duì)象參數(shù)。

let obj = {a: 1};
Object.assign(obj, undefined) === obj    // true
Object.assign(obj, null) === obj         // true

如果非對(duì)象參數(shù)為其他類型的值(即數(shù)值、字符串和布爾值),也不會(huì)報(bào)錯(cuò)。但是,除了字符串會(huì)以數(shù)組形式拷貝入目標(biāo)對(duì)象,其他值都不會(huì)產(chǎn)生效果。這是因?yàn)橹挥凶址陌b對(duì)象,會(huì)產(chǎn)生可枚舉屬性。

let v1 = "abc";
let v2 = true;
let v3 = 10;

let obj = Object.assign({}, v1, v2, v3);
console.log(obj)  // { "0": "a", "1": "b", "2": "c" }
3. 目標(biāo)對(duì)象 + 源對(duì)象...
(1) 屬性值為 nullundefined 的屬性會(huì)正常合并

Object.assign() 不會(huì)跳過那些屬性值為 nullundefined 的源對(duì)象。

var o1 = { a: null, b: 1};
var o2 = { c: undefined };
    
var obj = Object.assign({}, o1, o2);
obj   // {a: null, b: 1, c: undefined}
(2) 同名屬性的替換

如果目標(biāo)對(duì)象與源對(duì)象中的屬性具有相同的鍵,則目標(biāo)對(duì)象屬性將被源中的屬性覆蓋。后來的源的屬性將類似地覆蓋早先的屬性。

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);
obj    // { a: 1, b: 2, c: 3 }
(3) 淺拷貝

Object.assign() 方法實(shí)行的是淺拷貝,而不是深拷貝??截惖氖菍傩灾怠<偃缭磳?duì)象的屬性值是一個(gè)指向?qū)ο蟮囊?,它也只拷貝那個(gè)引用值。

var obj1 = { a: 0 , b: { c: 0 } };
var obj2 = Object.assign({}, obj1);
obj2   // { a: 0, b: { c: 0 } };

obj2.b.c = 3;
obj1   // { a: 0, b: { c: 3 } };
obj2   // { a: 0, b: { c: 3 } };
(4) 數(shù)組的處理

Object.assign() 可以用來處理數(shù)組,但是會(huì)把數(shù)組視為鍵值為數(shù)組下標(biāo)的對(duì)象來合并,然而最終的返回形式也是數(shù)組。

Object.assign([1, 2, 3], [4, 5])  // [4, 5, 3]

Object.assign({0:1,1:2,2:3},{0:4,1:5})  // {0: 4, 1: 5, 2: 3}
(5) 存取器屬性的處理

Object.assign() 如果遇到存取器定義的屬性,會(huì)只拷貝值。

var obj = {
  foo: 1,
  get bar() { return 2; }
};

var copy = Object.assign({}, obj); 
copy  // { foo: 1, bar: 2 }

因此必須使用 Object.getOwnPropertyDescriptors() 方法配合 Object.defineProperties() 方法,就可以實(shí)現(xiàn)正確拷貝。但僅限于可拷貝 gettersetter ,對(duì)于屬性的引用類型還是屬于淺拷貝。

var obj = {
  foo: { a : 0 },
  get bar() { return 2; }
};
var target = Object.defineProperties({},
  Object.getOwnPropertyDescriptors(obj)
);
Object.getOwnPropertyDescriptor(target, "bar")
// { get : ? bar(),
   set : undefined,
   enumerable : true, 
   configurable : true }
   
obj.foo.a = 6
target.foo.a   // 6
常見用途 1. 為對(duì)象添加屬性
class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
}

上面方法通過 Object.assign() 方法,將 x 屬性和 y 屬性添加到 Point 類的對(duì)象實(shí)例。

2. 為對(duì)象添加方法
Object.assign(SomeClass.prototype, {
  someMethod(arg1, arg2) { ··· },
  anotherMethod() { ··· }
});

// 等同于下面的寫法
SomeClass.prototype.someMethod = function (arg1, arg2) { ··· };
SomeClass.prototype.anotherMethod = function () { ··· };
3. 淺克隆對(duì)象
let obj = {a:5};
function clone(origin) {
  return Object.assign({}, origin);
}
let aaa = clone(obj);  // {a:5}

不過,采用這種方法克隆,只能克隆原始對(duì)象自身的值,不能克隆它繼承的值。如果想要保持繼承鏈,可以采用下面的代碼。

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin);
  return Object.assign(Object.create(originProto), origin);
}
4. 合并多個(gè)對(duì)象
let merge = (target, ...sources) => Object.assign(target, ...sources);

如果希望合并后返回一個(gè)新對(duì)象,可以改寫上面函數(shù),對(duì)一個(gè)空對(duì)象合并。

let merge = (...sources) => Object.assign({}, ...sources);
5. 為屬性指定默認(rèn)值
const DEFAULTS = {
  a: 0,
  b: "ccc"
};

function copy(options) {
  options = Object.assign({}, DEFAULTS, options);
  // ...
}

注意,由于存在淺拷貝的問題,DEFAULTS對(duì)象和options對(duì)象的所有屬性的值,最好都是簡單類型,不要指向另一個(gè)對(duì)象。否則,DEFAULTS對(duì)象的該屬性很可能不起作用。

參考鏈接:Object.assign()

深拷貝 1. JSON.parse(JSON.stringify(obj))
var obj1 = { a: 0 , b: { c: 0}};
var obj2 = JSON.parse(JSON.stringify(obj1));
obj1.b.c = 4;
obj2    // { a: 0, b: { c: 0}}

但由于 JSON 的局限性,該方法也不是萬能的。比如,如果對(duì)象的屬性是 undefined、函數(shù)、symbolXML 對(duì)象,該屬性會(huì)被 JSON.stringify() 過濾掉,導(dǎo)致拷貝時(shí)會(huì)缺少屬性。

let obj = {
  name:"dora",
  sayHello:function(){ console.log("Hello World"); }
}

let cloneObj = JSON.parse(JSON.stringify(obj));
console.log(cloneObj); // {name: "dora"}
2. 利用遞歸對(duì)每一層都重新創(chuàng)建對(duì)象并賦值從而實(shí)現(xiàn)深拷貝
function deepClone(source){
  let targetObj = source.constructor === Array ? [] : {}; 
  for(let keys in source){
    if(source.hasOwnProperty(keys)){
      if(source[keys] && typeof source[keys] === "object"){
        targetObj[keys] = source[keys].constructor === Array ? [] : {};
        targetObj[keys] = deepClone(source[keys]);
      }else{
        targetObj[keys] = source[keys];
      }
    }
  }
  return targetObj;
}

let obj = { a: { b: 1, c: 2 }, sayHello: function(){ console.log("Hello World"); } }
let cloneObj = deepClone(obj);

obj.a.b = 4
obj       // {a:{b: 4, c: 2},sayHello:? ()}
cloneObj  // {a:{b: 1, c: 2},sayHello:? ()}

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

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

相關(guān)文章

  • Python實(shí)用技法第33篇:字符串連接合并

    摘要:上一篇文章實(shí)用技法第篇對(duì)齊文本字符串下一篇文章問題我們想將許多小字符串合并成一個(gè)大的字符串。示例如下對(duì)于不必要的字符串連接操作也要引起重視。有時(shí)候在技術(shù)上并非必需的時(shí)候,程序員們也會(huì)忘乎所以地使用字符串連接操作。 上一篇文章: Python實(shí)用技法第32篇:對(duì)齊文本字符串下一篇文章:  問題 我們想將許多小字符串合并成一個(gè)大的字符串。  解決方案 如果想要合并的字符串在一個(gè)序列或可迭代...

    JayChen 評(píng)論0 收藏0
  • js淺拷貝拷貝幾種方法

    摘要:但這兩種拷貝有一個(gè)問題就是只能賦值一層,假設(shè)我們有如下數(shù)據(jù)結(jié)構(gòu)臧三小明小芳我們會(huì)發(fā)現(xiàn)打印出的結(jié)果如下上圖可看出的結(jié)果均變了,這并不是我們想要的結(jié)果,所以我們要用到深拷貝。 一個(gè)項(xiàng)目開發(fā)中經(jīng)常會(huì)用到需要復(fù)制一個(gè)對(duì)象或者數(shù)組,但是卻不能改變?cè)紝?duì)象,所以就要用到拷貝,拷貝又分深拷貝和淺拷貝,今天列舉一下幾種拷貝形式。 一、淺拷貝 (1) Object.assign() Object.ass...

    wing324 評(píng)論0 收藏0
  • Object 屬性與方法全接觸

    摘要:一切對(duì)象都是的實(shí)例,一切函數(shù)都是的實(shí)例,是構(gòu)造函數(shù),函數(shù)是的實(shí)例,是對(duì)象,對(duì)象是的實(shí)例,可以說與是一對(duì)密不可分的兄弟,讓我們一起解開與的神秘面紗,本章主要了解相關(guān)知識(shí),下章再來看構(gòu)造函數(shù)可以創(chuàng)建一個(gè)對(duì)象包裝器中所有對(duì)象都來自所有對(duì)象從繼承方 一切對(duì)象都是 Object 的實(shí)例,一切函數(shù)都是 Function 的實(shí)例,Object 是構(gòu)造函數(shù),函數(shù)是 Function 的實(shí)例,F(xiàn)unct...

    YJNldm 評(píng)論0 收藏0
  • 淺探j(luò)s深拷貝和淺拷貝

    摘要:接下來就讓我們更細(xì)致的探究中的深淺拷貝??偨Y(jié)以上對(duì)深拷貝和淺拷貝做了簡單的介紹,在深拷貝的實(shí)現(xiàn)上也只介紹了最簡單的實(shí)現(xiàn)形式,并未考慮復(fù)雜情況以及相應(yīng)優(yōu)化,想要對(duì)深拷貝有更深入的了解,需要大家花時(shí)間去深入研究,或者可以關(guān)注我后續(xù)文章的動(dòng)態(tài)。 對(duì)象和數(shù)組的拷貝對(duì)我來說一直都是一個(gè)比較模糊的概念,一直有點(diǎn)一知半解,但是在實(shí)際工作中又偶爾會(huì)涉及到,有時(shí)候還會(huì)一不小心掉坑里,不知道大家有沒有同樣...

    habren 評(píng)論0 收藏0
  • javascript拷貝VS淺拷貝

    摘要:深拷貝淺拷貝本文主要對(duì)深拷貝淺拷貝的解釋及實(shí)現(xiàn)做一下簡單記錄。之所以會(huì)有深拷貝與淺拷貝之分,是因?yàn)椴煌瑪?shù)據(jù)類型的數(shù)據(jù)在內(nèi)存中的存儲(chǔ)區(qū)域不一樣。但注意,只能做一層屬性的淺拷貝。 深拷貝VS淺拷貝 本文主要對(duì)深拷貝&淺拷貝的解釋及實(shí)現(xiàn)做一下簡單記錄。原文鏈接,歡迎star。 之所以會(huì)有深拷貝與淺拷貝之分,是因?yàn)椴煌瑪?shù)據(jù)類型的數(shù)據(jù)在內(nèi)存中的存儲(chǔ)區(qū)域不一樣。 堆和棧是計(jì)算機(jī)中劃分出來用來存儲(chǔ)的...

    Nekron 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

econi

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<