最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳細(xì)聊聊JS中不一樣的深拷貝

 更新時間:2022年10月16日 09:14:36   作者:當(dāng)然是黑貓警長啦  
對于js中的對象的深拷貝在項(xiàng)目的開發(fā)中比較常用到,這篇文章主要給大家介紹了關(guān)于JS中不一樣的深拷貝的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

對于深拷貝這個概念在面試中時常被提起,面試官可能讓你實(shí)現(xiàn)深拷貝需要考慮那些因素,或者直接讓你手寫封裝一個深拷貝,那么今天就和大家探討一下一個讓面試官感到牛的深拷貝,

1.思考

眾所周知普通的數(shù)據(jù)類型是值存儲,而復(fù)雜類型是通過開辟內(nèi)存空間來存儲數(shù)據(jù)的,我們通過內(nèi)存地址從而查找數(shù)據(jù),為了可以完全得到一個與原對象一模一樣但又沒有內(nèi)存地址關(guān)聯(lián)的深拷貝,我們需要考慮的因素其實(shí)有很多, 1.Object.create()創(chuàng)造的對象 , Object.create()詳細(xì)介紹

  let obj = Object.create(null)
            obj.name = '張三'
            obj.age = 22

這個對象是一個沒有原型的對象,大部分對象都有自己的原型,可以使用公共的方法,但這個卻不行,我們是不是應(yīng)該把它考慮進(jìn)去?

2.symbol作為屬性名的情況 Symbol詳細(xì)介紹 以及 for in 詳細(xì)介紹

let obj = {
            name: 'aa',
            age: 22,
            [Symbol('a')]: '獨(dú)一無二的'
            }

對于帶有symbol的屬性,在 for in 的迭代中是不可枚舉的,我們是不是需要考慮如何解決?

3.對于修改對象的屬性描述 Object.defineProperty()

let obj = { name: 'ayu', age: 22, sex: '男' }
Object.defineProperty(obj, 'age', {
    enumerable: true,
    configurable: true,
    value: 22,
    writable: false
})

這里我們改寫了原對象的屬性描述,age變得無法枚舉,for in 也失去效果,并且很多默認(rèn)的屬性描述信息,我們是不是在拷貝后也應(yīng)該和原對象保持一致?

4.對象的循環(huán)引用

let obj = { name: 'ayu', age: 22, sex: '男' }
obj.e = e

obj對象中有個e的屬性指向obj,造成相互引用,當(dāng)我們在封裝深拷貝時,主要是通過遞歸來逐層查找屬性值的情況,然后對其進(jìn)行操作,如果出現(xiàn)這個情況,就會死循環(huán)遞歸造成棧內(nèi)存溢出,這種情況難道也不值得考慮嘛?

5.一些特殊的對象 都說萬物皆對象,對象其實(shí)有很多類型,正則,日期(Date),等都需要特殊處理 而函數(shù)和數(shù)組就比較簡單

6.深拷貝的多數(shù)要點(diǎn) 也就是當(dāng)一個對象里面嵌套了多層對象,這個大家應(yīng)該都知道,我們通常一般使用遞歸去處理,再結(jié)合上面分析的因素就可以封裝函數(shù)了

const isComplexDataType = (obj) => (typeof obj === 'object' || typeof obj === 'function') && obj !== null
const deepClone = function (obj, hash = new WeakMap()) {
    if (obj.constructor === Date) return new Date(obj) // 日期對象直接返回一個新的日期對象
    if (obj.constructor === RegExp) return new RegExp(obj) //正則對象直接返回一個新的正則對象
    //如果循環(huán)引用了就用 weakMap 來解決
    if (hash.has(obj)) return hash.get(obj)
    let allDesc = Object.getOwnPropertyDescriptors(obj)
    //遍歷傳入?yún)?shù)所有鍵的特性
    let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)
    //繼承原型鏈
    hash.set(obj, cloneObj)
    for (let key of Reflect.ownKeys(obj)) {
        cloneObj[key] =
            isComplexDataType(obj[key]) && typeof obj[key] !== 'function' ? deepClone(obj[key], hash) : obj[key]
    }
    return cloneObj
}

思路 從deepclone這個函數(shù)開始說起

  • 1.如果對象的構(gòu)造器是Date構(gòu)造器,則我們使用Dte構(gòu)造器再構(gòu)造一個Date
  • 如果對象的構(gòu)造器是正則構(gòu)造器再構(gòu)造一個正則
  • WeakMap我們先不提,allDesc是拿到原對象所有的屬性(可枚舉以及不可枚舉)以及對應(yīng)的屬性描述信息
  • cloneObj是我們根據(jù)第三步拷貝的一個新的對象的信息,不過是一個淺拷貝,而且我們考慮了原型不存在的情況 Object.assin與Object.create的區(qū)別
  • 通過for of 循環(huán) Reflect.ownKeys(obj) Reflect.ownKeys()用法 (Reflect.ownKeys()可以遍歷對象自身所有的屬性(symbol,不可枚舉都可以),然后重新將obj的key以及對應(yīng)的值賦值給cloneObj,并且對obj[key]的值做了討論,當(dāng)它是對象并且不是函數(shù)時,我們遞歸處理,否則里面為普通值,直接賦給ObjClone

對于deepClone的第二個參數(shù)WeakMap來講, 請大家想想最開始我們提到的一個問題,我們有一個對象,然后我們填了了一個屬性,屬性為這個對象,這是在相互引用,如果我們處理這樣的對象,也使用遞歸處理,那么就是死循環(huán),因此我們需要一個數(shù)據(jù)結(jié)構(gòu)來解決,每次我們遞歸處理的時候,都把obj,以及賦值的cloneobj對應(yīng)存儲,當(dāng)遇到死循環(huán)的時候直接return這個對象即可 WeakMap詳細(xì)介紹·

(本文用到大量ES5以后的API,推薦閱讀阮一峰老師的ES6,這樣才能理解的透徹)

總結(jié)

到此這篇關(guān)于JS中不一樣的深拷貝的文章就介紹到這了,更多相關(guān)JS深拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 微信小程序?qū)崿F(xiàn)錄音

    微信小程序?qū)崿F(xiàn)錄音

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)錄音,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • JS控制文本域只讀或可寫屬性的方法

    JS控制文本域只讀或可寫屬性的方法

    這篇文章主要介紹了JS控制文本域只讀或可寫屬性的方法,涉及javascript針對頁面元素屬性的動態(tài)操作技巧,需要的朋友可以參考下
    2016-06-06
  • JavaScript NodeTree導(dǎo)航欄(菜單項(xiàng)JSON類型/自制)

    JavaScript NodeTree導(dǎo)航欄(菜單項(xiàng)JSON類型/自制)

    利用閑暇時間自己做了個JavaScript NodeTree,網(wǎng)上有很多類似的效果,本例主要是練練手,鞏固下知識,感興趣的朋友可以了解下,或許對你學(xué)習(xí)NodeTree導(dǎo)航欄有所幫助,認(rèn)為好的就分享嘍
    2013-02-02
  • 淺談js中的變量名和函數(shù)名重名

    淺談js中的變量名和函數(shù)名重名

    下面小編就為大家?guī)硪黄獪\談js中的變量名和函數(shù)名重名。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 前端構(gòu)建工具之gulp的語法教程

    前端構(gòu)建工具之gulp的語法教程

    這篇文章主要給大家介紹了關(guān)于前端構(gòu)建工具之gulp語法的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來跟著小編一起學(xué)習(xí)學(xué)習(xí)下吧。
    2017-06-06
  • JS是否可以跨文件同時控制多個iframe頁面的應(yīng)用技巧

    JS是否可以跨文件同時控制多個iframe頁面的應(yīng)用技巧

    這篇文章給大家詳細(xì)介紹了JS是否可以跨文件同時控制多個iframe頁面的應(yīng)用技巧,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2007-12-12
  • 用js來刷新當(dāng)前頁面保留參數(shù)的具體實(shí)現(xiàn)

    用js來刷新當(dāng)前頁面保留參數(shù)的具體實(shí)現(xiàn)

    本文為大家詳細(xì)介紹下如何使用js來刷新當(dāng)前頁面保留參數(shù),下面有個不錯的實(shí)現(xiàn)大家可以看看
    2013-12-12
  • JS 添加網(wǎng)頁桌面快捷方式的代碼詳細(xì)整理

    JS 添加網(wǎng)頁桌面快捷方式的代碼詳細(xì)整理

    如何添加桌面快捷?很多網(wǎng)友都有這個疑問;JS 點(diǎn)擊添加網(wǎng)頁桌面快捷方式的代碼,需要的朋友可以參考下
    2012-12-12
  • javascript實(shí)現(xiàn)電商放大鏡效果

    javascript實(shí)現(xiàn)電商放大鏡效果

    這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)電商放大鏡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Webpack打包詳細(xì)流程及代碼

    Webpack打包詳細(xì)流程及代碼

    這篇文章主要給大家介紹了關(guān)于Webpack打包詳細(xì)流程及代碼的相關(guān)資料,Webpack是一款非常流行的打包工具,它的主要作用是將項(xiàng)目中的各個模塊打包成靜態(tài)資源,以便于在瀏覽器中加載和運(yùn)行,需要的朋友可以參考下
    2024-01-01

最新評論

周宁县| 安顺市| 五莲县| 浪卡子县| 松江区| 平顶山市| 慈利县| 忻州市| 丰镇市| 江油市| 辽宁省| 江陵县| 延边| 普定县| 长岭县| 大邑县| 天祝| 绥德县| 兰溪市| 咸宁市| 桃源县| 宝兴县| 遵义市| 布拖县| 达尔| 台湾省| 维西| 青铜峡市| 临汾市| 临洮县| 梁河县| 桓仁| 绵竹市| 上虞市| 个旧市| 肥城市| 舒兰市| 西充县| 庆元县| 绥德县| 土默特右旗|