一柄粹、 數(shù)據(jù)類型
js的數(shù)據(jù)類型分為基本數(shù)據(jù)類型(String, Number, Boolean, Null, Undefined,Symbol)和引用數(shù)據(jù)類型。
- 基本數(shù)據(jù)類型:直接存儲(chǔ)在棧中的數(shù)據(jù)铐刘。
- 引用數(shù)據(jù)類型:棧中存儲(chǔ)的是該對(duì)象的引用地址陪每,真實(shí)的數(shù)據(jù)存放在堆內(nèi)存中。引用數(shù)據(jù)類型在棧中存儲(chǔ)了指針。當(dāng)解釋器尋找引用值時(shí)檩禾,會(huì)首先檢索其在棧中的地址挂签,取到地址后從堆中獲得實(shí)體。
- 保存在棧內(nèi)存的必須是大小固定的數(shù)據(jù)盼产,引用類型的大小不固定饵婆,只能保存在堆內(nèi)存,把它的地址寫在棧內(nèi)存供訪問戏售。
- 如果是基本數(shù)據(jù)類型侨核,是按值訪問,操作的就是變量保存的值灌灾。如果是引用類型的值搓译,只能通過保存在變量中的引用類型地址來操作實(shí)際對(duì)象。
二锋喜、賦值些己、淺拷貝和深拷貝
只準(zhǔn)對(duì) object 和 array 這樣的引用數(shù)據(jù)類型的。
賦值:當(dāng)我們把一個(gè)對(duì)象賦值給一個(gè)新的變量時(shí)嘿般,賦的其實(shí)是該對(duì)象的在棧中的引用地址段标,而不是堆中的數(shù)據(jù)。兩個(gè)對(duì)象指向的是同一個(gè)存儲(chǔ)空間炉奴,無論哪個(gè)對(duì)象發(fā)生改變逼庞,其實(shí)都是改變的存儲(chǔ)空間的內(nèi)容,因此瞻赶,兩個(gè)對(duì)象是聯(lián)動(dòng)的赛糟。
-
淺拷貝:淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身共耍,新舊對(duì)象共享一塊內(nèi)存虑灰。淺拷貝只能拷貝一層的基本數(shù)據(jù)類型,多層后就無法拷貝到了痹兜。淺拷貝比賦值多了一層穆咐。
function shallowCopy(obj) { var prop = {}; for (var i in obj) { if (obj.hasOwnProperty(i)) { prop[i] = obj[i]; } } return prop; }
深拷貝:深拷貝會(huì)在堆內(nèi)存中開辟一個(gè)新的區(qū)域存放新的值,新值和舊值不共享內(nèi)存字旭。修改新值不影響原值对湃。
三、實(shí)現(xiàn)方式
-
淺拷貝的實(shí)現(xiàn)方式
(1)Object.assign():可以把任意多個(gè)的源對(duì)象自身的可枚舉屬性拷貝給目標(biāo)對(duì)象遗淳,然后返回目標(biāo)對(duì)象拍柒。
(2)lodash的clone方法
(3)擴(kuò)展...操作符
(4)Array.prototype.concat,數(shù)組的拼接方法
(5)Array.prototype.slice屈暗,數(shù)組的截取方法
(6)手寫淺拷貝
-
深拷貝的實(shí)現(xiàn)方式
(1)JSON.parse(JSON.stringify()):可以處理數(shù)組和對(duì)象的深拷貝拆讯,但是不能處理函數(shù)和正則等
如果obj里存在***時(shí)間對(duì)象***脂男,得到的是***字符串*** 存在***RegExp、Error***對(duì)象种呐,得到的是***空對(duì)象*** 存在***函數(shù)宰翅、undefined***,會(huì)把函數(shù)和undefined***丟失*** 存在***NaN爽室、Infinity和-Infinity***汁讼,會(huì)變成***null*** 存在***構(gòu)造函數(shù)***生成的,構(gòu)造函數(shù)會(huì)被***丟棄***阔墩; 對(duì)象中存在循環(huán)引用(環(huán)形變量)會(huì)報(bào)錯(cuò)
(2)lodash的cloneDeep函數(shù)
(3)jQuery.extend函數(shù)
(4)手寫遞歸實(shí)現(xiàn)
四嘿架、使用場景
深拷貝
在前臺(tái)發(fā)請求從后臺(tái)獲取數(shù)據(jù)的時(shí)候,獲取的一般都是json格式的對(duì)象啸箫,我們一般要對(duì)這些數(shù)據(jù)進(jìn)行操作耸彪,但是這些數(shù)據(jù)可能有其他地方也需要使用,就可能會(huì)造成很多隱性問題忘苛,對(duì)數(shù)據(jù)做一次深拷貝搜囱,就能讓我們更安全的操作數(shù)據(jù)了,就不會(huì)出現(xiàn)原數(shù)據(jù)的破壞柑土。
從服務(wù)器fetch到數(shù)據(jù)之后我將其存放在store中,通過props傳遞給界面绊汹,然后我需要對(duì)這堆數(shù)據(jù)進(jìn)行修改稽屏,那涉及到修改就一定有保存和取消,所以我們需要將這堆數(shù)據(jù)拷貝到其他地方西乖。