javascript
js 浅拷贝直接赋值_JS中的赋值、浅拷贝与深拷贝
作者:奚杰
拷貝是寫(xiě)代碼中經(jīng)常使用的方法。淺拷貝與深拷貝是指拷貝的兩種情況。本文將深入探究JS的賦值、淺拷貝與深拷貝。
數(shù)據(jù)類(lèi)型
在探究深拷貝與淺拷貝之前,我們先梳理一下JS的數(shù)據(jù)類(lèi)型。在JavaScript中,數(shù)據(jù)類(lèi)型有兩大類(lèi)。一類(lèi)是基本數(shù)據(jù)類(lèi)型,一類(lèi)是引用數(shù)據(jù)類(lèi)型。
基本數(shù)據(jù)類(lèi)型有五種:number、string、boolean、null、undefined。基本數(shù)據(jù)類(lèi)型存放在棧中。存放在棧中的數(shù)據(jù)具有數(shù)據(jù)大小確定,內(nèi)存空間大小可以分配、直接按值存放的特點(diǎn)。所以存放在棧中的數(shù)據(jù)可以直接訪問(wèn)。在JavaScript中,基本的數(shù)據(jù)類(lèi)型值是不可更改的。可能這一點(diǎn)不符合我們平常的使用認(rèn)知。我們?cè)谛薷淖址蚱渌緮?shù)據(jù)類(lèi)型變量時(shí),實(shí)際上是返回了一個(gè)新的值,而不是【改變】原始值。
而對(duì)于引用數(shù)據(jù)類(lèi)型,是存放在堆內(nèi)存中。引用數(shù)據(jù)類(lèi)型的變量并不是存放的實(shí)際值,而是一個(gè)存放在棧內(nèi)存的指針,該指針指向堆內(nèi)存中的某個(gè)地址。每個(gè)數(shù)據(jù)所占的空間大小不一致,需要根據(jù)情況進(jìn)行特定的分配。與基本數(shù)據(jù)類(lèi)型不同,引用類(lèi)型的值是可以改變的。
賦值:傳值與傳址
有了對(duì)JavaScript數(shù)據(jù)類(lèi)型的一定了解后,我們接下來(lái)看看不同類(lèi)型的數(shù)據(jù)類(lèi)型在賦值時(shí)的區(qū)別。
對(duì)于基本數(shù)據(jù)類(lèi)型來(lái)說(shuō),當(dāng)我們進(jìn)行賦值操作(=)時(shí),實(shí)際上是在內(nèi)存中新開(kāi)一段棧內(nèi)存,然后再將值賦值到新的棧中。
舉個(gè)例子:
let a = 1 let b = a a = 5 console.log(a) // 5 console.log(b) // 1對(duì)于上述語(yǔ)句,b變量雖然是a變量的復(fù)制,但與a變量是獨(dú)立互不影響的變量。
而對(duì)于引用數(shù)據(jù)類(lèi)型來(lái)說(shuō),在進(jìn)行賦值操作時(shí),實(shí)際上是把變量的地址傳給了另一個(gè)變量,所以稱(chēng)為傳址。傳址之后,兩個(gè)變量就指向同一個(gè)地址,兩者的操作是互有影響的。
例:
let a = { age: 12 } let b = aa.age = 13 console.log(a.age) // 13 console.log(b.age) // 13b.age = 14 console.log(a.age) // 14 console.log(b.age) // 14淺拷貝與深拷貝
只有當(dāng)拷貝引用數(shù)據(jù)類(lèi)型時(shí),拷貝才存在淺拷貝與深拷貝之分。
淺拷貝
淺拷貝就是指創(chuàng)建一個(gè)新對(duì)象,該對(duì)象擁有原始對(duì)象第一層屬性的精確拷貝。即:如果原始對(duì)象的屬性是基本類(lèi)型數(shù)據(jù),則拷貝的就是基本數(shù)據(jù)類(lèi)型的值;如果原始對(duì)象的屬性是引用類(lèi)型,則拷貝的是內(nèi)存地址。當(dāng)原始對(duì)象的引用類(lèi)型屬性發(fā)生改變時(shí),拷貝對(duì)象的對(duì)應(yīng)屬性值也會(huì)發(fā)生變化。這里需要強(qiáng)調(diào)一下,淺拷貝與賦值是有所區(qū)別的,賦值時(shí)與原數(shù)據(jù)指向同一對(duì)象,而淺拷貝則指向了不同對(duì)象。
讓我們來(lái)實(shí)現(xiàn)一個(gè)淺拷貝方法。
function shallowCopy(src) {const dist = {}for (let prop in src) {if (src.hasOwnProperty(prop)) {dist[prop] = src[prop]}}return dist }深拷貝
淺拷貝是對(duì)原始對(duì)象第一層屬性的精確拷貝,而深拷貝則是對(duì)原始對(duì)象所有層級(jí)屬性的遞歸精確拷貝。
深拷貝的實(shí)現(xiàn)
JSON
function deepCopy (src) {let temp = JSON.stringify(src)let dist = JSON.parse(temp)return dist }遞歸實(shí)現(xiàn)
function deepCopy (src) {if (typeof src !== 'object') {return src}if (src == null) {return null}let dist = Array.isArray(src) ? [] : {}if (src && typeof src === "object") {for (let prop in src) {if (src.hasOwnProperty(prop)) {// 如果子屬性為引用數(shù)據(jù)類(lèi)型,遞歸復(fù)制if (src[prop] && typeof src[prop] === "object") {dist[prop] = deepCopy(src[prop])} else {// 如果是基本數(shù)據(jù)類(lèi)型,只是簡(jiǎn)單的復(fù)制dist[prop] = src[prop]}}}}return dist } 新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的js 浅拷贝直接赋值_JS中的赋值、浅拷贝与深拷贝的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql 中average_mysql
- 下一篇: php vim 补全,Vim 不使用 t