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

資訊專欄INFORMATION COLUMN

lodash之cloneDeep淺析

chemzqm / 3977人閱讀

摘要:淺拷貝和深拷貝本質(zhì)上的原因是對象引用的是地址,直接賦值會吧引用地址也復制給新值。深拷貝是會遞歸源數(shù)據(jù),吧新值得引用地址給換掉。對遞歸對遞歸調(diào)用是否是類型數(shù)組這里主要是會有個的特殊數(shù)組返回的特殊數(shù)組其他方法庫或等

淺拷貝和深拷貝

本質(zhì)上的原因是對象引用的是地址,直接賦值會吧引用地址也復制給新值。
淺復制只會將對象的各個屬性進行依次復制,會把引用地址也復制。
深拷貝是會遞歸源數(shù)據(jù),吧新值得引用地址給換掉。

lodash的cloneDeep

入口



const CLONE_DEEP_FLAG = 1
const CLONE_SYMBOLS_FLAG = 4

function cloneDeep(value) {
  return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG)
}

核心邏輯

function baseClone(value, bitmask, customizer, key, object, stack) {
  let result
  const isDeep = bitmask & CLONE_DEEP_FLAG
  const isFlat = bitmask & CLONE_FLAT_FLAG
  const isFull = bitmask & CLONE_SYMBOLS_FLAG

  if (customizer) {
    result = object ? customizer(value, key, object, stack) : customizer(value)
  }
  if (result !== undefined) {
    return result
  }
  if (!isObject(value)) {
    return value
  }
  // 判斷是否數(shù)組
  const isArr = Array.isArray(value)
  // 獲取constructor
  const tag = getTag(value)
  if (isArr) {
    // 初始化一個長度和源相等的數(shù)組
    result = initCloneArray(value)
    // 不是deep就直接復制了事
    if (!isDeep) {
      return copyArray(value, result)
    }
  } else {
    const isFunc = typeof value == "function"
      // Buffer.isBuffer, 對于buffer對象就直接復制了事
    if (isBuffer(value)) {
      return cloneBuffer(value, isDeep)
    }
    if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
      // 是否需要繼承proto
      result = (isFlat || isFunc) ? {} : initCloneObject(value)
      if (!isDeep) {
        // 這里deepclone的isFlat是0,走copySymbols,這個方法主要是復制源上的Symbols
        return isFlat
          ? copySymbolsIn(value, copyObject(value, keysIn(value), result))
          : copySymbols(value, Object.assign(result, value))
      }
    } else {
      // 如果是func或error, WeakMap就直接返回了
      if (isFunc || !cloneableTags[tag]) {
        return object ? value : {}
      }
      // 對tag位true的類型進行clone
      result = initCloneByTag(value, tag, isDeep)
    }
  }
  // Check for circular references and return its corresponding clone.
  // 檢查循環(huán)引用并返回其相應的克隆。
  stack || (stack = new Stack)
  const stacked = stack.get(value)
  if (stacked) {
    return stacked
  }
  stack.set(value, result)
  // 對map遞歸clone
  if (tag == mapTag) {
    value.forEach((subValue, key) => {
      result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack))
    })
    return result
  }
  // 對set遞歸調(diào)用
  if (tag == setTag) {
    value.forEach((subValue) => {
      result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack))
    })
    return result
  }
  // 是否是TypedArray類型
  if (isTypedArray(value)) {
    return result
  }

  const keysFunc = isFull
    ? (isFlat ? getAllKeysIn : getAllKeys)
    : (isFlat ? keysIn : keys)

  const props = isArr ? undefined : keysFunc(value)
  arrayEach(props || value, (subValue, key) => {
    if (props) {
      key = subValue
      subValue = value[key]
    }
    // Recursively populate clone (susceptible to call stack limits).
    assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack))
  })
  return result
}

數(shù)組這里主要是會有個exec的特殊數(shù)組

function initCloneArray(array) {
  const { length } = array
  const result = new array.constructor(length)

  // Add properties assigned by `RegExp#exec`.
  // RegExp.exec返回的特殊數(shù)組
  if (length && typeof array[0] == "string" && hasOwnProperty.call(array, "index")) {
    result.index = array.index
    result.input = array.input
  }
  return result
}
其他方法

Underscore庫或JSON.parse等

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

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

相關(guān)文章

  • 前端面試題及答案 - JS篇

    摘要:中使用操作符具體做了哪些事情創(chuàng)建了一個空對象空對象的屬性指向構(gòu)造函數(shù)的屬性執(zhí)行構(gòu)造函數(shù),將的指向前端面試題及答案瀏覽器篇前端面試題及答案篇前端面試題及答案篇前端面試題及答案性能優(yōu)化篇 這篇文章并不是最全的前端面試題(沒有最全,只有更全),只是針對自己面試過程中遇到的一些難題、容易忽略的題做一個簡單的筆記,方便后面有面試需要的小伙伴們借鑒,后續(xù)內(nèi)容會不定時更新,有錯誤之處希望大家不吝指出...

    Shimmer 評論0 收藏0
  • JavaScript系列--淺析JavaScript解析賦值、淺拷貝和深拷貝的區(qū)別

    摘要:它將返回目標對象。有些文章說是深拷貝,其實這是不正確的。深拷貝相比于淺拷貝速度較慢并且花銷較大。拷貝前后兩個對象互不影響。使用深拷貝的場景完全改變變量之后對沒有任何影響,這就是深拷貝的魔力。 一、賦值(Copy) 賦值是將某一數(shù)值或?qū)ο筚x給某個變量的過程,分為: 1、基本數(shù)據(jù)類型:賦值,賦值之后兩個變量互不影響 2、引用數(shù)據(jù)類型:賦址,兩個變量具有相同的引用,指向同一個對象,相互之間有...

    laznrbfe 評論0 收藏0
  • JavaScript 深拷貝

    摘要:深拷貝是一件看起來很簡單的事情,但其實一點兒也不簡單。我們也可以利用這個實現(xiàn)對象的深拷貝。而是利用之前已經(jīng)拷貝好的值。深拷貝的詳細的源碼可以在這里查看。大功告成我們雖然的確解決了深拷貝的大部分問題。 js深拷貝是一件看起來很簡單的事情,但其實一點兒也不簡單。對于循環(huán)引用的問題還有一些內(nèi)置數(shù)據(jù)類型的拷貝,如Map, Set, RegExp, Date, ArrayBuffer 和其他內(nèi)置...

    zhangwang 評論0 收藏0
  • js深淺復制

    摘要:總結(jié)綜上所述,數(shù)組的深拷貝比較簡單,方法沒有什么爭議,對象的深拷貝,比較好的方法是用的方法實現(xiàn),或者遞歸實現(xiàn),比較簡單的深復制可以使用實現(xiàn)參考資料知乎中的深拷貝和淺拷貝深入剖析的深復制 深淺復制對比 因為JavaScript存儲對象都是存地址的,所以淺復制會導致 obj 和obj1 指向同一塊內(nèi)存地址。我的理解是,這有點類似數(shù)據(jù)雙向綁定,改變了其中一方的內(nèi)容,都是在原來的內(nèi)存基礎(chǔ)上做...

    Apollo 評論0 收藏0

發(fā)表評論

0條評論

chemzqm

|高級講師

TA的文章

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