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

資訊專欄INFORMATION COLUMN

也來探討一下Object.assign

kuangcaibao / 896人閱讀

摘要:如果值為或,它將創(chuàng)建并返回一個(gè)空對(duì)象,否則,它將返回一個(gè)對(duì)應(yīng)于給定值的對(duì)象。如果該值已經(jīng)是一個(gè)對(duì)象,它將返回該值。此方法不會(huì)更改現(xiàn)有的數(shù)組,而是返回一個(gè)新的數(shù)組。所以我們可以使用遞歸實(shí)現(xiàn)一個(gè)下面就直接貼代碼了,略啰嗦,歡迎拍磚

Object.assign 是什么?

此處直接復(fù)制mdn文檔的內(nèi)容如下:

The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.

翻譯一下也就是:

Object.assign()方法用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象。它會(huì)返回目標(biāo)對(duì)象。

為了便于理解,此處貼出mdn的對(duì)Object.assign的polyfill

if (typeof Object.assign != "function") {
  // Must be writable: true, enumerable: false, configurable: true
  Object.defineProperty(Object, "assign", {
    value: function assign(target, varArgs) { // .length of function is 2
      "use strict";
      if (target == null) { // TypeError if undefined or null
        throw new TypeError("Cannot convert undefined or null to object");
      }

      var to = Object(target);

      for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index];

        if (nextSource != null) { // Skip over if undefined or null
          for (var nextKey in nextSource) {
            // Avoid bugs when hasOwnProperty is shadowed
            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
              to[nextKey] = nextSource[nextKey];
            }
          }
        }
      }
      return to;
    },
    writable: true,
    configurable: true
  });
}

其中的Object構(gòu)造函數(shù)為給定的值創(chuàng)建一個(gè)對(duì)象包裹器。如果值為null或undefined,它將創(chuàng)建并返回一個(gè)空對(duì)象,否則,它將返回一個(gè)Type對(duì)應(yīng)于給定值的對(duì)象。如果該值已經(jīng)是一個(gè)對(duì)象,它將返回該值。
舉個(gè)栗子?

Object(1)
// Number {1}
Object("")
// String {"", length: 0}
Object(false)
// Boolean {false}

從polyfill的代碼不難看出,Object.assign 就是將所傳參數(shù)當(dāng)中的對(duì)象的可枚舉屬性的值覆蓋到第一個(gè)對(duì)象上,那么由于js當(dāng)中的object,array是引用類型,所以對(duì)與對(duì)象,數(shù)組的覆蓋其實(shí)只是覆蓋了對(duì)數(shù)組,對(duì)象的引用,也即 淺copy

mdn栗子來一枚

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 }
如何實(shí)現(xiàn)深copy?

來個(gè)redux 當(dāng)中reducer 嵌套數(shù)據(jù)更新的栗子?

add(state, { payload: todo }) {
      const todos = state.a.b.todos.concat(todo);
      const b = Object.assign({},state.a.b,{todos})
      const a = Object.assign({},state.a,);
      return Object({},state,{a});
    },

上面的栗子當(dāng)中concat()方法用于合并兩個(gè)或多個(gè)數(shù)組。此方法不會(huì)更改現(xiàn)有的數(shù)組,而是返回一個(gè)新的數(shù)組??梢岳斫鉃槔胏oncat方法創(chuàng)建了一個(gè)新的todos數(shù)組,這樣就可以避免對(duì)數(shù)據(jù)的修改影響到了舊的todos數(shù)組,然后將新的todos數(shù)組使用Object.assign 給新的b,以此,僅僅實(shí)現(xiàn)了sate對(duì)象中將深層次的todos的一個(gè)‘深copy’。
但是如果state還有其他的屬性的值為對(duì)象或者數(shù)組,簡(jiǎn)單的使用Object.assign 只是復(fù)制了一個(gè)引用。所以在寫reducer的時(shí)候需要盡量避免state嵌套的太深,為了安全,我們可以使用 updeep來更新數(shù)據(jù),或者直接使用不可變數(shù)據(jù),此處不再多說,繼續(xù)探討Object.assign.

實(shí)現(xiàn)一個(gè)deepCopy?
前面探討了對(duì)象當(dāng)中單個(gè)屬性值的深copy,但是如果有多個(gè)值,怎么辦呢?一個(gè)一個(gè)手動(dòng)找出來?當(dāng)然不行啊,這樣一點(diǎn)兒也不好玩兒
為了實(shí)現(xiàn)一個(gè)deepCopy,我們先簡(jiǎn)單了解一下js的數(shù)據(jù)類型:
值類型:數(shù)值、布爾值、null、undefined。

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

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

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

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

了解了js的數(shù)組類型之后,那么實(shí)現(xiàn)一個(gè)深copy其實(shí)主要就是解決引用類型的copy,數(shù)組和對(duì)象無限往下拆,最終其屬性也是值類型組成的。所以我們可以使用遞歸實(shí)現(xiàn)一個(gè)deepCopy,下面就直接貼代碼了,略啰嗦,歡迎?拍磚

function detectType(source) {
    return Object.prototype.toString
        .call(source)
        .split(/[[,s,]]/)[2]
        .toLowerCase();
}
function deepCopy(source, copyDeep) {
    var type = detectType(source);
    if (!(type === "object" || type === "array")) {
        return source;
    }
    var newObject = type === "array" ? source.slice() :Object.assign({}, source);
    if (!copyDeep) {
        return newObject;
    }
    Object.keys(newObject).forEach(function (key) {
        newObject[key] = deepCopy(newObject[key], true);
    });
    return newObject;
}

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

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

相關(guān)文章

  • JavaScript·隨記 深拷貝 vs. 淺拷貝

    摘要:而在這個(gè)運(yùn)算符的相關(guān)用例中,往往會(huì)涉及到其他知識(shí)點(diǎn),深拷貝和淺拷貝就是其中之一。即對(duì)象的淺拷貝會(huì)對(duì)主對(duì)象的值進(jìn)行拷貝,而該值有可能是一個(gè)指針,指向內(nèi)存中的同一個(gè)對(duì)象。,可以看到深拷貝和淺拷貝是對(duì)復(fù)制引用類型變量而言的。 在ES6的系列文章中,基本都會(huì)提到Spread——擴(kuò)展運(yùn)算符(...)。而在這個(gè)運(yùn)算符的相關(guān)用例中,往往會(huì)涉及到其他知識(shí)點(diǎn),深拷貝和淺拷貝就是其中之一。 背景知識(shí) 在討...

    RyanQ 評(píng)論0 收藏0
  • 也來談?wù)凴PC

    摘要:前言,顧名思義即遠(yuǎn)程過程調(diào)用,可以說是分部式應(yīng)用的基礎(chǔ),也是概念中的核心部分。對(duì)于來說,可以分為之間的調(diào)用與和其他平臺(tái)之間的調(diào)用。和分別代表了這兩種模式。 前言 RPC,顧名思義即遠(yuǎn)程過程調(diào)用,可以說是分部式WEB應(yīng)用的基礎(chǔ),也是SOA概念中的核心部分。對(duì)于J2EE來說,可以分為JVM之間的調(diào)用與和其他平臺(tái)之間的調(diào)用。前者主要是RMI,而后者則五花八門,比如Apache的Thrift...

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

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

0條評(píng)論

kuangcaibao

|高級(jí)講師

TA的文章

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