對(duì)于引用類型來說:

發(fā)展壯大離不開廣大客戶長期以來的信賴與支持,我們將始終秉承“誠信為本、服務(wù)至上”的服務(wù)理念,堅(jiān)持“二合一”的優(yōu)良服務(wù)模式,真誠服務(wù)每家企業(yè),認(rèn)真做好每個(gè)細(xì)節(jié),不斷完善自我,成就企業(yè),實(shí)現(xiàn)共贏。行業(yè)涉及成都紙箱等,在網(wǎng)站建設(shè)公司、營銷型網(wǎng)站建設(shè)、WAP手機(jī)網(wǎng)站、VI設(shè)計(jì)、軟件開發(fā)等項(xiàng)目上具有豐富的設(shè)計(jì)經(jīng)驗(yàn)。
1、【賦值】是相當(dāng)于賦值了指針,并沒有重新開辟一個(gè)新的內(nèi)存空間。
也就是說:不管是多深的層次,只要有變化都會(huì)相互影響。
舉例子:
2、【淺拷貝】:會(huì)開辟新的內(nèi)存空間,但是只是對(duì)于引用類型里屬性類型為簡單類型的數(shù)據(jù)來說的(不會(huì)相互影響)。對(duì)于屬性類型為引用類型的數(shù)據(jù)來說是會(huì)復(fù)制他的指針指向,不會(huì)開辟新的內(nèi)存空間(改變引用類型的值,會(huì)相互影響)。
例子:
做了一個(gè)例子以為concat是深拷貝,因?yàn)槎紱]有相互影響,其實(shí)是寫錯(cuò)了,b[4]是引用類型,但是我直接給他賦值了,相當(dāng)于給這個(gè)引用類型重新開辟了一個(gè)新的內(nèi)存空間,所以不會(huì)影響到arr[4]。
例子如下:
對(duì)象的淺拷貝例子如下:
【深拷貝】:從里到外不管啥類型 都會(huì)重新開辟內(nèi)存空間,所以不會(huì)相互影響。可以遞歸,可以loadsh里的方法,jquery的extend(深淺都可以)
如何實(shí)現(xiàn)數(shù)組深拷貝和淺拷貝?
1.背景介紹
javascript分原始類型與引用類型。Array是引用類型,直接用“=”號(hào)賦值的話,只是把源數(shù)組的地址(或叫指針)賦值給目的數(shù)組,并沒有實(shí)現(xiàn)數(shù)組的數(shù)據(jù)的拷貝。這種方式的實(shí)現(xiàn)屬于淺拷貝。
深拷貝是開辟新的儲(chǔ)存空間,兩個(gè)對(duì)象對(duì)應(yīng)兩個(gè)不同的地址,修改一個(gè)對(duì)象的屬性,不會(huì)改變另一個(gè)對(duì)象的屬性。
2.知識(shí)剖析
一維數(shù)組的深拷貝方法:slice()和concat()
slice()的使用方法
slice()語法:arrayObj.slice(start,)
slice方法是通過參數(shù)start和end的傳入值來返回?cái)?shù)組中的一段,該方法不對(duì)原數(shù)組進(jìn)行操作,而是返回一個(gè)子數(shù)組
start:必需。規(guī)定從何處開始選取。如果是負(fù)數(shù),那么它規(guī)定從數(shù)組尾部開始算起的位置。也就是說,-1 指最后一個(gè)元素,-2 指倒數(shù)第二個(gè)元素,以此類推。
end:可選。規(guī)定從何處結(jié)束選取。該參數(shù)是數(shù)組片斷結(jié)束處的數(shù)組下標(biāo)。如果沒有指定該參數(shù),那么切分的數(shù)組包含從 start 到數(shù)組結(jié)束的所有元素。如果這個(gè)參數(shù)是負(fù)數(shù),那么它規(guī)定的是從數(shù)組尾部開始算起的元素。
返回值:返回一個(gè)新的數(shù)組,包含從 start 到 end (不包括該元素)的 arrayObject 中的元素(如果 end 未被規(guī)定,那么 slice() 方法會(huì)選取從 start 到數(shù)組結(jié)尾的所有元素)。
concat()的使用方法
concat()語法:arrayObject.concat(arrayX,arrayX,......,arrayX)
arrayX:必需,可以是具體的值,也可以是數(shù)組對(duì)象。可以是任意多個(gè)。
concat() 方法用于連接兩個(gè)或多個(gè)數(shù)組。 該方法不會(huì)改變現(xiàn)有的數(shù)組,而僅僅會(huì)返回一個(gè)新的數(shù)組。如果要進(jìn)行 concat() 操作的參 數(shù)是數(shù)組,那么添加的是數(shù)組中的元素,而不是數(shù)組。
3.常見問題
1、jquery中數(shù)組深拷貝辦法
語法:jQuery.extend( [deep ], target, object1 [, objectN ] )
將兩個(gè)或更多對(duì)象的內(nèi)容合并到第一個(gè)對(duì)象。
deep:可選。 Boolean類型 指示是否深度合并對(duì)象,默認(rèn)為false。如果該值為true,且多個(gè)對(duì)象的某個(gè)同名屬性也都是對(duì)象,則該"屬性對(duì)象"的屬性也將進(jìn)行合并。
2、什么是深拷貝?
深拷貝:指的是拷貝一個(gè)對(duì)象時(shí),不僅僅把對(duì)象的引用進(jìn)行復(fù)制,還把該對(duì)象引用的值也一起拷貝。這樣進(jìn)行深拷貝后的拷貝對(duì)象就和源對(duì)象互相獨(dú)立,其中任何一個(gè)對(duì)象的改動(dòng)都不會(huì)對(duì)另外一個(gè)對(duì)象造成影響。舉個(gè)例子,一個(gè)人叫張三,然后使用克隆技術(shù)以張三來克隆另外一個(gè)人叫李四,這樣張三和李四就是相互獨(dú)立的,不管張三缺胳膊還是李四少腿了都不會(huì)影響另外一個(gè)人。在.NET領(lǐng)域,值對(duì)象就是典型的例子,如int, Double以及結(jié)構(gòu)體和枚舉等。
3、什么是淺拷貝呢?
淺拷貝:指的是拷貝一個(gè)對(duì)象時(shí),僅僅拷貝對(duì)象的引用進(jìn)行拷貝,但是拷貝對(duì)象和源對(duì)象還是引用同一份實(shí)體。此時(shí),其中一個(gè)對(duì)象的改變都會(huì)影響到另一個(gè)對(duì)象。例如,一個(gè)人一開始叫張三,后來改名字為張老三了,可是他們還是同一個(gè)人,不管張三缺胳膊還是張老三少腿,都反應(yīng)在同一個(gè)人身上。在.NET中引用類型就是一個(gè)例子。
4 解決方案
jquery.extend()
語法:jQuery.extend( [deep ], target, object1 [, objectN ] )
將兩個(gè)或更多對(duì)象的內(nèi)容合并到第一個(gè)對(duì)象。
deep:可選。 Boolean類型 指示是否深度合并對(duì)象,默認(rèn)為false。如果該值為true,且多個(gè)對(duì)象的某個(gè)同名屬性也都是對(duì)象,則該"屬性對(duì)象"的屬性也將進(jìn)行合并。
5.編碼實(shí)戰(zhàn)
6.擴(kuò)展思考
slice和concat對(duì)數(shù)組深拷貝的局限性
slice和concat這兩個(gè)方法,僅適用于對(duì)不包含引用對(duì)象的一維數(shù)組的深拷貝。對(duì)于數(shù)組內(nèi)部存在對(duì)象和數(shù)組,當(dāng)改變對(duì)象屬性和內(nèi)部數(shù)組的元素后,深拷貝的數(shù)組同樣也發(fā)生了改變。
最近的學(xué)習(xí)中,仔細(xì)研究了下深拷貝和淺拷貝,下面就來簡單的總結(jié)下。
首先我們了解下兩種 數(shù)據(jù)類型 :
1、基本類型:像Number、String、Boolean等這種為基本類型
2、復(fù)雜類型:Object和Array
接著我們分別來了解下淺拷貝和深拷貝,深拷貝和淺拷貝是只針對(duì)Object和Array這樣的復(fù)雜類型的。
淺拷貝 :
可以看出,對(duì)于對(duì)象或數(shù)組類型,當(dāng)我們將a賦值給b,然后更改b中的屬性,a也會(huì)隨著變化。也就是說a和b指向了同一塊內(nèi)存,所以修改其中任意的值,另一個(gè)值都會(huì)隨之變化,這就是淺拷貝。
深拷貝 :
剛剛我們了解了什么是淺拷貝,那么相應(yīng)的,如果給b放到新的內(nèi)存中,將a的各個(gè)屬性都復(fù)制到新內(nèi)存里,就是深拷貝。
也就是說,當(dāng)b中的屬性有變化的時(shí)候,a內(nèi)的屬性不會(huì)發(fā)生變化。
那么除了上面簡單的賦值引用,還有哪些方法使用了 淺拷貝 呢?
Object.assign()
在MDN上介紹Object.assign():”O(jiān)bject.assign() 方法用于將所有可枚舉的屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象。它將返回目標(biāo)對(duì)象。”
復(fù)制一個(gè)對(duì)象
可以看到,Object.assign()拷貝的只是屬性值,假如源對(duì)象的屬性值是一個(gè)指向?qū)ο蟮囊茫仓豢截惸莻€(gè)引用值。所以O(shè)bject.assign()只能用于淺拷貝或是合并對(duì)象。這是Object.assign()值得注意的地方。
那么下面我們就來說說復(fù)雜的 深拷貝 。
jQuery.extend()
說到深拷貝,第一想到的就是jQuery.extend()方法,下面我們簡單看下jQuery.extend()的使用。
jQuery.extend( [deep ], target, object1 [, objectN ] ),其中deep為Boolean類型,如果是true,則進(jìn)行深拷貝。
我們還是用上面的數(shù)據(jù)來看下extend()方法。
通過上面的對(duì)比可以看出,當(dāng)使用extend()進(jìn)行深拷貝的時(shí)候,對(duì)象的所有屬性都添加到target中了。
我們知道了extend()可以進(jìn)行深拷貝,那么extend()是如何實(shí)現(xiàn)深拷貝的呢?
先來看下jQuery.extend()源碼
主要看下關(guān)于深拷貝的部分,取第一個(gè)參數(shù),如果是boolean類型的,就賦值給deep,下面如果deep為true(也就是進(jìn)行深拷貝),就遞歸調(diào)用extend(),這樣就將對(duì)象的所有屬性都添加到了target中實(shí)現(xiàn)了深拷貝。
JSON.parse()和JSON.stringify()
上面的jQuery源碼是否讓你眼花繚亂?有沒有什么辦法無腦實(shí)現(xiàn)深拷貝呢?JSON.parse()和JSON.stringify()給了我們一個(gè)基本的解決辦法。
可以看到改變targetCopy并沒有改變原始的target,繼承的屬性也沒有丟失,因此實(shí)現(xiàn)了基本的深拷貝。
但是用JSON.parse()和JSON.stringify()會(huì)有一個(gè)問題。
JSON.parse()和JSON.stringify()能正確處理的對(duì)象只有Number、String、Array等能夠被json表示的數(shù)據(jù)結(jié)構(gòu),因此函數(shù)這種不能被json表示的類型將不能被正確處理。
上面的例子可以看出,hello這個(gè)屬性由于是函數(shù)類型,使用JSON.parse()和JSON.stringify()后丟失了。
因此JSON.parse()和JSON.stringify()還是需要謹(jǐn)慎使用。
JS 中深拷貝的幾種實(shí)現(xiàn)方法
1、使用遞歸的方式實(shí)現(xiàn)深拷貝
//使用遞歸的方式實(shí)現(xiàn)數(shù)組、對(duì)象的深拷貝
function deepClone1(obj) {
//判斷拷貝的要進(jìn)行深拷貝的是數(shù)組還是對(duì)象,是數(shù)組的話進(jìn)行數(shù)組拷貝,對(duì)象的話進(jìn)行對(duì)象拷貝
var objClone = Array.isArray(obj) ? [] : {};
//進(jìn)行深拷貝的不能為空,并且是對(duì)象或者是
if (obj typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] typeof obj[key] === "object") {
objClone[key] = deepClone1(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
2、通過 JSON 對(duì)象實(shí)現(xiàn)深拷貝
//通過js的內(nèi)置對(duì)象JSON來進(jìn)行數(shù)組對(duì)象的深拷貝
function deepClone2(obj) {
var _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone;
}
JSON對(duì)象實(shí)現(xiàn)深拷貝的一些問題
* 無法實(shí)現(xiàn)對(duì)對(duì)象中方法的深拷貝
3、通過jQuery的extend方法實(shí)現(xiàn)深拷貝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array);
4、Object.assign()拷貝
當(dāng)對(duì)象中只有一級(jí)屬性,沒有二級(jí)屬性的時(shí)候,此方法為深拷貝,但是對(duì)象中有對(duì)象的時(shí)候,此方法,在二級(jí)屬性以后就是淺拷貝。
5、lodash函數(shù)庫實(shí)現(xiàn)深拷貝
lodash很熱門的函數(shù)庫,提供了 lodash.cloneDeep()實(shí)現(xiàn)深拷貝
新聞標(biāo)題:jquery深拷貝,js 深拷貝
瀏覽路徑:http://chinadenli.net/article43/dsgjdes.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、響應(yīng)式網(wǎng)站、網(wǎng)站維護(hù)、、網(wǎng)站導(dǎo)航、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)