久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      一文帶你詳細(xì)了解JavaScript中的深拷貝

      一文帶你詳細(xì)了解JavaScript中的深拷貝

      前端(vue)入門到精通課程:進(jìn)入學(xué)習(xí)
      Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點(diǎn)擊使用

      網(wǎng)上有很多關(guān)于深拷貝的文章,但是質(zhì)量良莠不齊,有很多都考慮得不周到,寫的方法比較簡(jiǎn)陋,難以令人滿意。本文旨在完成一個(gè)完美的深拷貝,大家看了如果有問題,歡迎一起補(bǔ)充完善。

      評(píng)價(jià)一個(gè)深拷貝是否完善,請(qǐng)檢查以下問題是否都實(shí)現(xiàn)了:

      • 基本類型數(shù)據(jù)是否能拷貝?

      • 鍵和值都是基本類型的普通對(duì)象是否能拷貝?

      • Symbol作為對(duì)象的key是否能拷貝?

      • DateRegExp對(duì)象類型是否能拷貝?

      • MapSet對(duì)象類型是否能拷貝?

      • Function對(duì)象類型是否能拷貝?(函數(shù)我們一般不用深拷貝)

      • 對(duì)象的原型是否能拷貝?

      • 不可枚舉屬性是否能拷貝?

      • 循環(huán)引用是否能拷貝?

      怎樣?你寫的深拷貝夠完善嗎?

      深拷貝的最終實(shí)現(xiàn)

      這里先直接給出最終的代碼版本,方便想快速了解的人查看,當(dāng)然,你想一步步了解可以繼續(xù)查看文章余下的內(nèi)容:

      function deepClone(target) {     const map = new WeakMap()          function isObject(target) {         return (typeof target === 'object' && target ) || typeof target === 'function'     }      function clone(data) {         if (!isObject(data)) {             return data         }         if ([Date, RegExp].includes(data.constructor)) {             return new data.constructor(data)         }         if (typeof data === 'function') {             return new Function('return ' + data.toString())()         }         const exist = map.get(data)         if (exist) {             return exist         }         if (data instanceof Map) {             const result = new Map()             map.set(data, result)             data.forEach((val, key) => {                 if (isObject(val)) {                     result.set(key, clone(val))                 } else {                     result.set(key, val)                 }             })             return result         }         if (data instanceof Set) {             const result = new Set()             map.set(data, result)             data.forEach(val => {                 if (isObject(val)) {                     result.add(clone(val))                 } else {                     result.add(val)                 }             })             return result         }         const keys = Reflect.ownKeys(data)         const allDesc = Object.getOwnPropertyDescriptors(data)         const result = Object.create(Object.getPrototypeOf(data), allDesc)         map.set(data, result)         keys.forEach(key => {             const val = data[key]             if (isObject(val)) {                 result[key] = clone(val)             } else {                 result[key] = val             }         })         return result     }      return clone(target) }
      登錄后復(fù)制

      1. JavaScript數(shù)據(jù)類型的拷貝原理

      先看看JS數(shù)據(jù)類型圖(除了Object,其他都是基礎(chǔ)類型):
      一文帶你詳細(xì)了解JavaScript中的深拷貝
      在JavaScript中,基礎(chǔ)類型值的復(fù)制是直接拷貝一份新的一模一樣的數(shù)據(jù),這兩份數(shù)據(jù)相互獨(dú)立,互不影響。而引用類型值(Object類型)的復(fù)制是傳遞對(duì)象的引用(也就是對(duì)象所在的內(nèi)存地址,即指向?qū)ο蟮闹羔槪喈?dāng)于多個(gè)變量指向同一個(gè)對(duì)象,那么只要其中的一個(gè)變量對(duì)這個(gè)對(duì)象進(jìn)行修改,其他的變量所指向的對(duì)象也會(huì)跟著修改(因?yàn)樗鼈冎赶虻氖峭粋€(gè)對(duì)象)。如下圖:
      一文帶你詳細(xì)了解JavaScript中的深拷貝

      2. 深淺拷貝

      深淺拷貝主要針對(duì)的是Object類型,基礎(chǔ)類型的值本身即是復(fù)制一模一樣的一份,不區(qū)分深淺拷貝。這里我們先給出測(cè)試的拷貝對(duì)象,大家可以拿這個(gè)obj對(duì)象來測(cè)試一下自己寫的深拷貝函數(shù)是否完善:

      // 測(cè)試的obj對(duì)象 const obj = {     // =========== 1.基礎(chǔ)數(shù)據(jù)類型 ===========     num: 0, // number     str: '', // string     bool: true, // boolean     unf: undefined, // undefined     nul: null, // null     sym: Symbol('sym'), // symbol     bign: BigInt(1n), // bigint      // =========== 2.Object類型 ===========     // 普通對(duì)象     obj: {         name: '我是一個(gè)對(duì)象',         id: 1     },     // 數(shù)組     arr: [0, 1, 2],     // 函數(shù)     func: function () {         console.log('我是一個(gè)函數(shù)')     },     // 日期     date: new Date(0),     // 正則     reg: new RegExp('/我是一個(gè)正則/ig'),     // Map     map: new Map().set('mapKey', 1),     // Set     set: new Set().add('set'),     // =========== 3.其他 ===========     [Symbol('1')]: 1  // Symbol作為key };  // 4.添加不可枚舉屬性 Object.defineProperty(obj, 'innumerable', {     enumerable: false,     value: '不可枚舉屬性' });  // 5.設(shè)置原型對(duì)象 Object.setPrototypeOf(obj, {     proto: 'proto' })  // 6.設(shè)置loop成循環(huán)引用的屬性 obj.loop = obj
      登錄后復(fù)制

      obj對(duì)象在Chrome瀏覽器中的結(jié)果:

      一文帶你詳細(xì)了解JavaScript中的深拷貝

      2.1 淺拷貝

      淺拷貝: 創(chuàng)建一個(gè)新的對(duì)象,來接受你要重新復(fù)制或引用的對(duì)象值。如果對(duì)象屬性是基本的數(shù)據(jù)類型,復(fù)制的就是基本類型的值給新對(duì)象;但如果屬性是引用數(shù)據(jù)類型,復(fù)制的就是內(nèi)存中的地址,如果其中一個(gè)對(duì)象改變了這個(gè)內(nèi)存中的地址所指向的對(duì)象,肯定會(huì)影響到另一個(gè)對(duì)象。

      首先我們看看一些淺拷貝的方法(詳細(xì)了解可點(diǎn)擊對(duì)應(yīng)方法的超鏈接):

      方法 使用方式 注意事項(xiàng)
      Object.assign() Object.assign(target, ...sources)
      說明:用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象分配到目標(biāo)對(duì)象。它將返回目標(biāo)對(duì)象。
      1.不會(huì)拷貝對(duì)象的繼承屬性;
      2.不會(huì)拷貝對(duì)象的不可枚舉的屬性;
      3.可以拷貝 Symbol 類型的屬性。
      展開語(yǔ)法 let objClone = { ...obj }; 缺陷和Object.assign()差不多,但是如果屬性都是基本類型的值,使用擴(kuò)展運(yùn)算符進(jìn)行淺拷貝會(huì)更加方便。
      Array.prototype.concat()拷貝數(shù)組 const new_array = old_array.concat(value1[, value2[, ...[, valueN]]]) 淺拷貝,適用于基本類型值的數(shù)組
      Array.prototype.slice()拷貝數(shù)組 arr.slice([begin[, end]]) 淺拷貝,適用于基本類型值的數(shù)組

      這里只列舉了常用的幾種方式,除此之外當(dāng)然還有其他

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)