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

資訊專(zhuān)欄INFORMATION COLUMN

javascript中拷貝

hedzr / 1958人閱讀

摘要:簡(jiǎn)單來(lái)說(shuō),就是把復(fù)制過(guò)程中的源對(duì)象都記錄下來(lái),以及對(duì)應(yīng)的拷貝對(duì)象,碰到屬性值是之前復(fù)制過(guò)的對(duì)象的情況,的屬性值是,就把對(duì)應(yīng)的拷貝對(duì)象給它,,而不進(jìn)行遞歸深拷貝。例如的屬性值是的地址,那么拷貝過(guò)程中,的屬性值就是的地址。

基礎(chǔ)類(lèi)型與引用(地址) 例子一
let a = "l am a string"
let b = 6
let obj = {
  c: "l am an obj",
  d: 123
}
let obj1 = obj
console.log(obj1) // { c: "l am an obj", d: 123 }
obj1.c = "l am an obj1"
console.log(obj) // { c: "l am an obj1", d: 123 }
console.log(obj1) // { c: "l am an obj1", d: 123 }

變量obj存的是地址address01,執(zhí)行let obj1 = obj后,變量obj1存的還是address01。就好像主臥室(obj),或大房間(obj1),都指的是房間號(hào)為address01的房間。所以,你說(shuō)“換掉大房間的床”,obj1.c = "l am an obj1",等同于“換掉主臥室的床”,因?yàn)槎际恰皳Q掉房間號(hào)為address01的房間里的床”。

例子二
let a = "l am a string"
let b = 6
let obj = {
  c: "l am an obj",
  d: 123
}
let obj1 = {}
obj1.c = obj.c
obj1.d = obj.d
console.log(obj1) // { c: "l am an obj", d: 123 }
obj1.c = "l am an obj1"
console.log(obj) // { c: "l am an obj", d: 123 }
console.log(obj1) // { c: "l am an obj1", d: 123 }

變量obj存的是地址address01,執(zhí)行let obj1 = {}后,變量obj1得到了一個(gè)新的地址address02。現(xiàn)在不僅有房間號(hào)為address01的主臥室(obj),還有房間號(hào)為address02的次臥(obj1),在那里你可以布置你自己的新房間。你可以先說(shuō)“要一張和主臥一樣的床”,obj1.c = obj.c,再說(shuō)“還要一臺(tái)和主臥一樣的燈”,obj1.d = obj.d,最后你又覺(jué)得床不舒服,“換了張床”,obj1.c = "l am an obj1",但這些都不會(huì)影響主臥的床obj.c。

例子三
let a = "l am a string"
let b = 6
let obj = {
  c: "l am an obj",
  d: 123,
  e: [1, 3, 5]
}
let obj1 = {}
obj1.c = obj.c
obj1.d = obj.d
obj1.e = obj.e
console.log(obj1) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] }
obj1.c = "l am an obj1"
obj1.e[0] = 2
console.log(obj) // { c: "l am an obj", d: 123, e: [ 2, 3, 5 ] }
console.log(obj1) // { c: "l am an obj1", d: 123, e: [ 2, 3, 5 ] }

主臥里面還可以有衛(wèi)生間obj.e的呢,obj.e存的也是地址adress03,只要是對(duì)象或數(shù)組都存的是地址。這時(shí)obj1.e = obj.e,存的就是主臥的衛(wèi)生間的房間號(hào)address03。目前只有一個(gè)衛(wèi)生間,你知道衛(wèi)生間的地址adress03,保存在obj1.e中,然后你就知道如何“把衛(wèi)生間的熱水器換掉”,obj1.e[0] = 2。

例子四
let a = "l am a string"
let b = 6
let obj = {
  c: "l am an obj",
  d: 123,
  e: [1, 3, 5]
}
let obj1 = {}
obj1.c = obj.c
obj1.d = obj.d
obj1.e = obj.e
console.log(obj1) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] }
obj1.c = "l am an obj1"
obj1.e = "l am not an arr"
console.log(obj) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] }
console.log(obj1) // { c: "l am an obj1", d: 123, e: "l am not an arr" }

后來(lái)你覺(jué)得知道主臥的衛(wèi)生間的地址adress03有什么用,有那閑工夫還不如用來(lái)放個(gè)柜子,故obj1.e = "l am not an arr",這樣做以后,沒(méi)有了衛(wèi)生間的地址,你就不能在主臥的衛(wèi)生間里搗亂了。

例子五
let a = "l am a string"
let b = 6
let obj = {
  c: "l am an obj",
  d: 123,
  e: [1, 3, 5]
}
let obj1 = {}
obj1.c = obj.c
obj1.d = obj.d
obj1.e = []
for (let i = 0; i < obj.e.length; i++) {
  obj1.e[i] = obj.e[i]
}
console.log(obj1) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] }
obj1.c = "l am an obj1"
obj1.e[0] = 2
console.log(obj) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] }
console.log(obj1) // { c: "l am an obj1", d: 123, e: [ 2, 3, 5 ] }

其實(shí)你還是想要個(gè)獨(dú)立衛(wèi)生間的,obj1.e = [],這樣你得到了房間號(hào)為adress04的房間,然后你按照主臥衛(wèi)生間的樣子來(lái)改造這個(gè)房間for (let i = 0; i < obj.e.length; i++) { obj1.e[i] = obj.e[i] }。這時(shí)候有兩個(gè)獨(dú)立的衛(wèi)生間了,房間號(hào)分別是adress04adress03,盡管布局裝飾一樣,但還是兩個(gè)房間,賓館里的房間還都一樣呢,但它們有不同的房間號(hào),實(shí)際上是相互獨(dú)立的房間。你換adress04房間的熱水器,obj1.e[0] = 2,并不會(huì)影響房間adress03房間。

抽象例子五的復(fù)制過(guò)程

即深拷貝

let a = "l am a string"
let b = 6
let obj = {
  c: "l am an obj",
  d: 123,
  e: [1, 3, 5]
}
function deepCopy(val) {
  if (!val || typeof val !== "object") {
    return val
  }
  let copy = Array.isArray(val) ? [] : {}
  for (key in val) {
    if (val.hasOwnProperty(key)) {
      if (val[key] && typeof val[key] === "object") {
        copy[key] = deepCopy(val[key])
      } else {
        copy[key] = val[key]
      }
    }
  }
  return copy
}

let obj1 = deepCopy(obj)
obj1.c = "l am an obj1"
obj1.e[0] = 2
console.log(obj) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] }
console.log(obj1) // { c: "l am an obj1", d: 123, e: [ 2, 3, 5 ] }
例子六
let a = "l am a string"
let b = 6
let obj = {
  c: "l am an obj",
  d: 123,
  e: {}
}
obj.e.parent = obj

let keyValArr = []
let copyArr = []

function deepCopy(val) {
  if (!val || typeof val !== "object") {
    return val
  }
  let copy = Array.isArray(val) ? [] : {}

  let index = keyValArr.indexOf(val)
  if (index === -1) {
    keyValArr.push(val)
    copyArr.push(copy)
  } else {
    return copyArr[index]
  }

  for (key in val) {
    if (val.hasOwnProperty(key)) {
      if (val[key] && typeof val[key] === "object") {
        copy[key] = deepCopy(val[key])
      } else {
        copy[key] = val[key]
      }
    }
  }
  return copy
}

let obj1 = deepCopy(obj)
obj1.e.parent.c = "l am an obj1"
console.log(obj) // { c: "l am an obj", d: 123, e: { parent: [Circular] } }
console.log(obj1) // { c: "l am an obj1", d: 123, e: { parent: [Circular] } }

總有人想尋根問(wèn)祖,obj.e.parent = obj,如此形成了環(huán),之前的代碼就要重新調(diào)整。簡(jiǎn)單來(lái)說(shuō),就是把復(fù)制過(guò)程中的源對(duì)象[obj, obj.e]都記錄下來(lái),以及對(duì)應(yīng)的拷貝對(duì)象[copy, copy.e],碰到屬性值是之前復(fù)制過(guò)的對(duì)象的情況,obj.e.parent的屬性值是obj,就把對(duì)應(yīng)的拷貝對(duì)象給它,copy.e.parent = copy,而不進(jìn)行遞歸深拷貝。
從地址的角度來(lái)說(shuō),復(fù)制過(guò)程中,把地址都記錄下來(lái),用valArr記錄源對(duì)象的地址[address01, address03],用copyArr記錄拷貝對(duì)象的地址[address02, address04],當(dāng)碰到需要拷貝的是之前記錄過(guò)源對(duì)象的地址時(shí),就把對(duì)應(yīng)的拷貝對(duì)象的地址返回。例如obj.e.parent的屬性值是obj的地址,那么拷貝過(guò)程中,obj1.e.parent的屬性值就是obj1的地址。

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

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

相關(guān)文章

  • JavaScript基礎(chǔ)心法——深淺拷貝

    摘要:原文地址基礎(chǔ)心法深淺拷貝歡迎。上面的代碼是最簡(jiǎn)單的利用賦值操作符實(shí)現(xiàn)了一個(gè)淺拷貝,可以很清楚的看到,隨著和改變,和也隨著發(fā)生了變化。展開(kāi)運(yùn)算符結(jié)論實(shí)現(xiàn)的是對(duì)象第一層的深拷貝。 原文地址:JavaScript基礎(chǔ)心法——深淺拷貝 歡迎star。 如果有錯(cuò)誤的地方歡迎指正。 淺拷貝和深拷貝都是對(duì)于JS中的引用類(lèi)型而言的,淺拷貝就只是復(fù)制對(duì)象的引用,如果拷貝后的對(duì)象發(fā)生變化,原對(duì)象也會(huì)發(fā)生...

    keithxiaoy 評(píng)論0 收藏0
  • JavaScript的淺拷貝與深拷貝

    摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 上一篇 JavaScript中的繼承 前言 文章開(kāi)始之前,讓我們先思考一下這幾個(gè)問(wèn)題: 為什么會(huì)有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實(shí)現(xiàn)淺拷貝與深拷貝 好了,問(wèn)題出來(lái)了,那么下面就讓我們帶著這幾個(gè)問(wèn)題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處...

    AZmake 評(píng)論0 收藏0
  • JavaScript的淺拷貝與深拷貝

    摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 為什么會(huì)有淺拷貝與深拷貝什么是淺拷貝與深拷貝如何實(shí)現(xiàn)淺拷貝與深拷貝好了,問(wèn)題出來(lái)了,那么下面就讓我們帶著這幾個(gè)問(wèn)題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處,還請(qǐng)看到的小伙伴多多指教,先行謝過(guò) 以下↓ 數(shù)據(jù)類(lèi)型在開(kāi)始了解 淺拷貝 與 深拷貝 之前,讓我們先...

    546669204 評(píng)論0 收藏0
  • Day14 - JavaScript 引用和值拷貝

    摘要:引用和值拷貝微信公眾號(hào)開(kāi)發(fā)企業(yè)級(jí)產(chǎn)品全棧開(kāi)發(fā)速成周末班首期班號(hào)正式開(kāi)班,歡迎搶座作者黎躍春追時(shí)間的人簡(jiǎn)介是推出的一個(gè)天挑戰(zhàn)。深拷貝與淺拷貝對(duì)比創(chuàng)建對(duì)象黎躍春淺拷貝深拷貝將對(duì)象轉(zhuǎn)換成字符串,打印時(shí)效果清晰。 Day14 - JavaScript 引用和值拷貝 (Node+Vue+微信公眾號(hào)開(kāi)發(fā))企業(yè)級(jí)產(chǎn)品全棧開(kāi)發(fā)速成周末班首期班(10.28號(hào)正式開(kāi)班,歡迎搶座) 作者:?黎躍春-追時(shí)間的...

    chanjarster 評(píng)論0 收藏0
  • JavaScript 數(shù)據(jù)結(jié)構(gòu)與算法之美 - 棧內(nèi)存與堆內(nèi)存 、淺拷貝與深拷貝

    摘要:棧內(nèi)存與堆內(nèi)存淺拷貝與深拷貝,可以說(shuō)是前端程序員的內(nèi)功,要知其然,知其所以然。棧內(nèi)存與堆內(nèi)存中的變量分為基本類(lèi)型和引用類(lèi)型。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 前言 想寫(xiě)好前端,先練好內(nèi)功。 棧內(nèi)存與堆內(nèi)存 、淺拷貝與深拷貝,可以說(shuō)是前端程序員的內(nèi)功,要知其然,知其所以然。 筆者寫(xiě)的 JavaScrip...

    dailybird 評(píng)論0 收藏0
  • JavaScript的淺拷貝和深拷貝

    摘要:在中可以通過(guò)添加一個(gè)參數(shù)來(lái)實(shí)現(xiàn)遞歸,調(diào)用就可以實(shí)現(xiàn)一個(gè)深拷貝。利用序列化實(shí)現(xiàn)一個(gè)深拷貝 在JavaScript中,對(duì)于Object和Array這類(lèi)引用類(lèi)型值,當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類(lèi)型值時(shí),這個(gè)值的副本其實(shí)是一個(gè)指針,兩個(gè)變量指向同一個(gè)堆對(duì)象,改變其中一個(gè)變量,另一個(gè)也會(huì)受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實(shí)例,也就是我們說(shuō)的淺拷貝和深拷貝 淺拷貝(shallow...

    ernest.wang 評(píng)論0 收藏0

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

0條評(píng)論

hedzr

|高級(jí)講師

TA的文章

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