国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JS之深拷貝與淺拷貝

這篇具有很好參考價(jià)值的文章主要介紹了JS之深拷貝與淺拷貝。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、理解

?深拷貝 與 淺拷貝

?針對(duì)于 引用類型(Object,Array,Function) 來說的

淺拷貝:在棧中分配一塊新內(nèi)存,拷貝需要拷貝的值,

? ? ? ? ? 對(duì)簡單數(shù)據(jù)類型,就是拷貝值;對(duì)復(fù)雜數(shù)據(jù)類型,就是拷貝了一份棧內(nèi)存儲(chǔ)的堆內(nèi)存的地址

?深拷貝:在堆中重新分配新內(nèi)存,存儲(chǔ)新的拷貝數(shù)據(jù);

????????????????在棧中分配新內(nèi)存,存儲(chǔ)新數(shù)據(jù)分配的堆的地址。

標(biāo)準(zhǔn)淺拷貝:

// =
let obj1 = obj
obj.a = '88888'
console.log(obj)
console.log( obj1)

結(jié)果:

JS之深拷貝與淺拷貝

實(shí)現(xiàn)方式:

?淺拷貝的實(shí)現(xiàn)方式:

? ? ? ? 1. 基于Object.assign()

? ? ? ? 2. 基于for in = 直接賦值

? ? ? ? 3. ... 原地展開

?深拷貝的三種實(shí)現(xiàn)方式:

? ? ? 1. 遞歸實(shí)現(xiàn)(重點(diǎn))

? ? ? 2. JSON.stringify + JSON.parse 方法

? ? ? 3. JQuery的$extend方法(了解)

?其他奇怪的api方法?可能非真正的深拷貝

? ? ?1. slice 一維數(shù)組深拷貝,多維拷貝不徹底(針對(duì)數(shù)組)

? ? ?2. Object.assign

? ? ?3.?Object.create

二、一些奇怪的api的使用及測(cè)試

1.Object.assign()

Object.assign用法:

? 用于將源對(duì)象的所有可枚舉屬性到目標(biāo)對(duì)象,返回目標(biāo)對(duì)象

?至少需要兩個(gè)對(duì)象做參數(shù):Object.assign(目標(biāo)對(duì)象, 源對(duì)象1,...)

?只要有一個(gè)參數(shù)不是對(duì)象,就會(huì)拋出TypeError錯(cuò)誤

?如果有同名屬性,后覆蓋前;只復(fù)制自身屬性(也會(huì)復(fù)制Symbol值的屬性),不復(fù)制不可枚舉/繼承屬性

?可用于: 為對(duì)象添加屬性或方法;克隆對(duì)象;合并多個(gè)對(duì)象;為屬性指定默認(rèn)值

拷貝實(shí)現(xiàn):

// Object.assign 
let obj = {
  a: 1,
  b: 2,
  c: [1, 2, 3],
  d: {
    g:777,
    s: {},
    f: function() { console.log('f')}
  }
}
let obj1 = Object.assign({}, obj)
console.log(obj1)

拷貝結(jié)果:

JS之深拷貝與淺拷貝

?拷貝測(cè)試:

對(duì)第一層的測(cè)試:

obj1.a = 666 // 對(duì)第一層的基本數(shù)據(jù)類型修改=>深拷貝
obj1.c = [] // 對(duì)第一層的引用數(shù)據(jù)類型 => 深拷貝
// obj1.c[0] = '000' // 對(duì)第一層的引用數(shù)據(jù)類型 內(nèi)的某一項(xiàng)進(jìn)行修改=>淺拷貝
//obj1.d.g = 8888 //
obj1.d.s.w = '9999999' // 對(duì)內(nèi)層引用數(shù)據(jù)類型進(jìn)行修改(添加)=>淺拷貝
console.log(obj)
console.log( obj1)

測(cè)試結(jié)果:

JS之深拷貝與淺拷貝

?其他測(cè)試:

obj1.c[0] = '000' // 對(duì)第一層的引用數(shù)據(jù)類型 內(nèi)的某一項(xiàng)進(jìn)行修改=>淺拷貝
obj1.d.g = 8888 // 對(duì)內(nèi)層基礎(chǔ)數(shù)據(jù)類型修改 => 淺拷貝
obj1.d.s.w = '9999999' // 對(duì)內(nèi)層引用數(shù)據(jù)類型某一項(xiàng) 進(jìn)行修改(添加)=>淺拷貝
obj1.d.f = {} // 對(duì)內(nèi)層引用數(shù)據(jù)類型 整體修改 => 淺拷貝
console.log(obj)
console.log( obj1)

測(cè)試結(jié)果:

JS之深拷貝與淺拷貝

小總結(jié):

?對(duì)拷貝的第一層的基礎(chǔ)數(shù)據(jù)類型 實(shí)現(xiàn)了深拷貝(修改拷貝值,不影響新值);

?對(duì)深層數(shù)據(jù),依然是淺拷貝,修改數(shù)據(jù)值會(huì)影響原數(shù)據(jù)

注意:當(dāng)整體修改第一層引用數(shù)據(jù)后,新對(duì)象的整個(gè)引用數(shù)據(jù)的指向應(yīng)該是修改后的,這時(shí)再對(duì)引用數(shù)據(jù)中某一項(xiàng)修改時(shí),不會(huì)影響原來的對(duì)象;但直接對(duì)于第一層引用數(shù)據(jù)類型的某一項(xiàng)進(jìn)行修改時(shí),還是會(huì)影響原來的對(duì)象。

2.Object.create

api用法:

?方法用于 創(chuàng)建一個(gè)新對(duì)象,使用現(xiàn)有的對(duì)象來提供新創(chuàng)建的對(duì)象的proto

?參數(shù): Object.create(proto新建對(duì)象的原型對(duì)象,[添加到新創(chuàng)建對(duì)象的可枚舉屬性])

?返回值:在指定原型對(duì)象上添加新屬性后的對(duì)象

拷貝:

// 3. Object.create 淺拷貝
let obj1 = Object.create(obj)
console.log(obj1) // obj1 是一個(gè)空對(duì)象,其原型為obj;obj1.__proto__是obj的淺拷貝
console.log(obj1.__proto__ === obj) // true

運(yùn)行結(jié)果:

JS之深拷貝與淺拷貝

淺拷貝,新對(duì)象的原型為舊對(duì)象

obj1 是一個(gè)空對(duì)象,其原型為obj;obj1.__proto__是obj的淺拷貝

3. ES6 ...擴(kuò)展運(yùn)算符

代碼實(shí)現(xiàn):

// ES6 擴(kuò)展運(yùn)算符
let obj1 = { ...obj }
console.log(obj1)

測(cè)試結(jié)果同Object.assign

4.slice+concat實(shí)現(xiàn)拷貝(針對(duì)數(shù)組)

slice:

實(shí)現(xiàn)及測(cè)試:

// 針對(duì)數(shù)組
let arr = ['a', 'b', 'c', {d:4}]

// slice
let arr1 = arr.slice(0)
// console.log(arr)
// console.log(arr1)

arr1[0] = '1'
arr1[3].d = '777'
console.log(arr)
console.log(arr1)

運(yùn)行結(jié)果:

JS之深拷貝與淺拷貝

?可見,slice 對(duì)于數(shù)組中的基礎(chǔ)數(shù)據(jù)類型,能夠?qū)崿F(xiàn)深拷貝,對(duì)于引用數(shù)據(jù)類型,無法實(shí)現(xiàn)深拷貝。

concat:

// concat
let arr1 = arr.concat()

// console.log(arr)
// console.log(arr1)

測(cè)試結(jié)果與slice相同。

三、實(shí)現(xiàn)深拷貝的三種方式

1. JSON.stringify + JSON.parse

拷貝實(shí)現(xiàn):

let obj = {
  a: 1,
  b: 2,
  c: [1, 2, 3],
  d: {
    g:777,
    s: {w:'www'},
    f: function() { console.log('f')}
  },
  e: undefined,
  p: NaN,
  date:new Date()
}
// JSON.stringify + JSON.parse 方法
let obj1 = JSON.parse(JSON.stringify(obj))
console.log(obj)
console.log(obj1)

結(jié)果截圖:

JS之深拷貝與淺拷貝

可見,拷貝對(duì)象無函數(shù)f、無undefined屬性e,即該方法無法實(shí)現(xiàn)對(duì)函數(shù)、對(duì)undefined值的拷貝?;

經(jīng)測(cè)試,為深拷貝。

該方法存在的問題:

1.對(duì)象中有時(shí)間類型時(shí),序列化后會(huì)變成字符串類型;

2.對(duì)象中有function、undefined類型的數(shù)據(jù),會(huì)直接丟失;

3.對(duì)象中有NaN、Infinity、-Infinity時(shí),序列化后會(huì)顯示null;

4.對(duì)象循環(huán)引用時(shí),會(huì)報(bào)錯(cuò)。

2.JQuery中的$.extend方法可以實(shí)現(xiàn)深拷貝(知道)

3.遞歸實(shí)現(xiàn)深拷貝(待升級(jí)完善版)

深拷貝的簡單遞歸實(shí)現(xiàn):

let obj = {
  a: 1,
  b: 2,
  c: [1, 2, 3],
  d: {
    g:777,
    s: {w:'www'},
    f: function() { console.log('f')}
  },
  e: undefined,
  p: NaN,
  date:new Date()
}

// 遞歸實(shí)現(xiàn)深拷貝--簡單版()
function deepClone(obj) {
  let newObj = null
  // if (obj === null) return obj//???
  if (typeof obj == 'undefined') return undefined
  if (typeof obj === 'function') return obj//淺拷貝函數(shù)?
  if (obj.constructor == Date) return new Date(obj)
  if(obj.constructor == RegExp) return new RegExp(obj)
  
  if (typeof obj == 'object') {
    newObj = obj instanceof Array ? [] : {}
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        newObj[key] = deepClone(obj[key])
      }
    }
  } else {
    newObj = obj
  }
  return newObj
}

let obj1 = deepClone(obj)
console.log(obj)
console.log(obj1)

運(yùn)行截圖:

JS之深拷貝與淺拷貝

復(fù)雜版:

// 深拷貝 復(fù)雜版?
function checkType(target) {
  console.log(Object.prototype.toString.call(target).slice(8,-1))
  return Object.prototype.toString.call(target).slice(8,-1)
}

function deepClone2(data) {
  const obj = checkType(data) === 'Array' ? [] : {}
  let arr = ['Object','Array']
  if (arr.includes(checkType(data))) {
    for (let key in data) {
      let value = data[key]
      //value為簡單類型,直接賦值
      if (!arr.includes(checkType(value))) {
        obj[key] = value
      } else {
        // 定義一個(gè)映射,初始化時(shí),將data本身加入映射中
        const map = new WeakMap()
        // 如果拷貝的是復(fù)雜數(shù)據(jù)類型第一次拷貝后存入map
        // 第二次再遇到該值時(shí),直接賦值為null,結(jié)束遞歸
        map.set(data, true)
        if (map.has(value)) {
          obj[key] = null
        } else {
          map.set(value, true);
          obj[key] = deepClone2(value)
        }
      }
    }
  } else {
    return data
  }
  return obj
}

let obj1 = deepClone2(obj)
console.log(obj)
console.log(obj1)

結(jié)果:

JS之深拷貝與淺拷貝

?文章來源地址http://www.zghlxwxcb.cn/news/detail-484476.html

到了這里,關(guān)于JS之深拷貝與淺拷貝的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java中的深拷貝與淺拷貝

    深拷貝和淺拷貝是編程中常用的兩種對(duì)象復(fù)制方式,它們?cè)趶?fù)制對(duì)象時(shí)處理對(duì)象內(nèi)部引用的方式上有所不同。 淺拷貝 淺拷貝(Shallow Copy)只復(fù)制對(duì)象的頂層結(jié)構(gòu),而不復(fù)制對(duì)象內(nèi)部的引用對(duì)象。換句話說,淺拷貝只復(fù)制對(duì)象的值類型字段和引用類型字段的引用,而不復(fù)制引

    2024年01月22日
    瀏覽(40)
  • 面試官:深拷貝與淺拷貝有啥區(qū)別?

    面試官:深拷貝與淺拷貝有啥區(qū)別?

    首先,明確一點(diǎn)深拷貝和淺拷貝是針對(duì)對(duì)象屬性為對(duì)象的,因?yàn)榛緮?shù)據(jù)類型在進(jìn)行賦值操作時(shí)(也就是拷貝)是直接將值賦給了新的變量,也就是該變量是原變量的一個(gè)副本,這個(gè)時(shí)候你修改兩者中的任何一個(gè)的值都不會(huì)影響另一個(gè),而對(duì)象或者引用數(shù)據(jù)來說在進(jìn)行淺拷貝

    2024年02月07日
    瀏覽(25)
  • Java中的集合及深拷貝與淺拷貝

    Java中的集合及深拷貝與淺拷貝

    Java是一種面向?qū)ο蟮木幊陶Z言,其中集合是常用的數(shù)據(jù)結(jié)構(gòu)之一,具有方便快捷的特點(diǎn)。在Java開發(fā)中,我們常常需要對(duì)集合進(jìn)行復(fù)制(拷貝)操作。但是,拷貝操作并不是簡單的復(fù)制,而應(yīng)該分為淺拷貝和深拷貝兩種不同的方式,本文將分別介紹Java中集合的淺拷貝和深拷貝

    2024年02月07日
    瀏覽(20)
  • 【Python】python深拷貝與淺拷貝詳解(必須掌握)

    深拷貝和淺拷貝是python必須要掌握的內(nèi)容,無論你是面試開發(fā)、測(cè)試、運(yùn)維等職位,只要是python,深拷貝與淺拷貝是面試官常問的一個(gè)重要知識(shí)點(diǎn)。 (關(guān)注“測(cè)試開發(fā)自動(dòng)化” 弓中皓,獲取更多學(xué)習(xí)內(nèi)容) 相同點(diǎn): 無論深拷貝還是淺拷貝都會(huì)創(chuàng)建一個(gè)新對(duì)象。即:拷貝出來

    2024年03月25日
    瀏覽(26)
  • 深入探索前端之道:JavaScript深拷貝與淺拷貝的解析與實(shí)現(xiàn)

    前端開發(fā)中,數(shù)據(jù)的復(fù)制是一個(gè)常見的操作。尤其是在處理對(duì)象和數(shù)組時(shí),我們需要考慮的是一個(gè)淺拷貝還是深拷貝。那么,什么是深拷貝和淺拷貝?它們?cè)谇岸碎_發(fā)中有什么作用?如何實(shí)現(xiàn)這兩種拷貝?這是我們?cè)诒疚膶⒂懻摰膯栴}。 淺拷貝 淺拷貝是一種數(shù)據(jù)復(fù)制方式,

    2024年02月10日
    瀏覽(24)
  • 深入理解 Java 引用類型:強(qiáng)壯、柔軟、脆弱、虛無的力量

    深入理解 Java 引用類型:強(qiáng)壯、柔軟、脆弱、虛無的力量

    ?? 大家好,我是 vnjohn,在互聯(lián)網(wǎng)企業(yè)擔(dān)任 Java 開發(fā),CSDN 優(yōu)質(zhì)創(chuàng)作者 ?? 推薦專欄:Spring、MySQL、Nacos、Java,后續(xù)其他專欄會(huì)持續(xù)優(yōu)化更新迭代 ??文章所在專欄:JVM ?? 我當(dāng)前正在學(xué)習(xí)微服務(wù)領(lǐng)域、云原生領(lǐng)域、消息中間件等架構(gòu)、原理知識(shí) ?? 向我詢問任何您想要的東西

    2024年02月11日
    瀏覽(21)
  • web前端面試-- js深拷貝的一些bug,特殊對(duì)象屬性(RegExp,Date,Error,Symbol,F(xiàn)unction)處理,循環(huán)引用weekmap處理

    web前端面試-- js深拷貝的一些bug,特殊對(duì)象屬性(RegExp,Date,Error,Symbol,F(xiàn)unction)處理,循環(huán)引用weekmap處理

    本人是一個(gè)web前端開發(fā)工程師,主要是vue框架,整理了一些面試題,今后也會(huì)一直更新,有好題目的同學(xué)歡迎評(píng)論區(qū)分享 ;-) web面試題專欄:點(diǎn)擊此處 在JavaScript中,深拷貝和淺拷貝是兩種不同的對(duì)象復(fù)制方式。 淺拷貝是指將一個(gè)對(duì)象的引用復(fù)制給另一個(gè)對(duì)象,這意味著兩個(gè)

    2024年02月07日
    瀏覽(28)
  • 前端JS代碼中Object類型數(shù)據(jù)的相關(guān)知識(shí)

    獲取Object類型數(shù)據(jù)的方式有兩種: 方括號(hào)獲?。?Object[\\\"arg1\\\"] 點(diǎn)·獲取: Object.arg1 前端遍歷Object類型數(shù)據(jù)的方式 遍歷JavaScript中的對(duì)象有幾種方法,包括使用for…in循環(huán)、Object.keys()方法、Object.values()方法和Object.entries()方法。以下是每種方法的示例代碼: Object對(duì)象中的日期類型

    2024年01月20日
    瀏覽(24)
  • js判斷類型:typeof Object.prototype.toString instanceof constructor有什么區(qū)別?一文講清楚

    js判斷類型:typeof Object.prototype.toString instanceof constructor有什么區(qū)別?一文講清楚

    相信很多小伙伴在使用js的過程中,經(jīng)常會(huì)需要對(duì)js的數(shù)據(jù)類型進(jìn)行判斷,而js中可以對(duì)數(shù)據(jù)類型進(jìn)行判斷的方法有很多種,最常見的有typeof、Object.prototype.toString、instanceof、constructor這四種,那么他們有什么區(qū)別呢? 目錄 js數(shù)據(jù)類型 typeof 為啥typeof會(huì)將null判斷為object Object.pr

    2024年02月11日
    瀏覽(27)
  • js面包屑,如何制作面包屑,什么是面包屑,又如何去理解面包屑是什么呢,對(duì)于不會(huì)應(yīng)該怎么辦呢?這篇文章告訴你。

    js面包屑,如何制作面包屑,什么是面包屑,又如何去理解面包屑是什么呢,對(duì)于不會(huì)應(yīng)該怎么辦呢?這篇文章告訴你。

    ??博主:鍋蓋噠 ??文章核心: 帶你了解原生js面包屑框架 目錄大綱 1.面包屑的概念與框架地址 2.功能框架預(yù)覽于介紹 框架效果預(yù)覽: 頁面架構(gòu)代碼預(yù)覽: HTML頁面預(yù)覽: ?權(quán)限驗(yàn)證介紹 3.面包屑的邏輯 ?下面就是面包屑邏輯 1.首先從login頁面進(jìn)入拿到渲染左側(cè)列表的值 2

    2024年02月14日
    瀏覽(38)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包