javascript深拷貝是初學者甚至有經驗的開發著,都會經常遇到問題,并不能很好的理解javascript的深拷貝。
深拷貝(deepClone)?
與深拷貝相對的就是淺拷貝,很多初學者在接觸這個感念的時候,是很懵逼的。
為啥要用深拷貝?
在很多情況下,我們都需要給變量賦值,給內存地址賦予一個值,但是在賦值引用值類型的時候,只是共享一個內存區域,導致賦值的時候,還跟之前的值保持一直性。
看一個具體的例子
// 給test賦值了一個對象var test = { a: 'a', b: 'b'};// 將test賦值給test2// 此時test和test2是共享了同一塊內存對象,這也就是淺拷貝var test2 = test;test2.a = 'a2';test.a === 'a2'// 為true
圖解:
這下就很好理解為什么引用值類型數據相互影響問題。
實現
實現一個深拷貝函數,就不得不說javascript的數值類型。
判斷javascript類型
javascript中有以下基本類型
類型 描述
undefined undefined類型只有一個值undefined,它是變量未被賦值時的值
null null類型也只有一個值null, 它是一個空的對象引用
Boolean Boolean有兩種取值true和false
String 它表示文本信息
Number 它表示數字信息
Object 它是一系列屬性的無序集合, 包括函數Function和數組Array
使用typeof是無法判斷function和array的,這里使用Object.prototype.toString方法。
[默認情況下,每個對象都會從Object上繼承到toString()方法,如果這個方法沒有被這個對象自身或者更接近的上層原型上的同名方法覆蓋(遮蔽),則調用該對象的toString()方法時會返回"[object type]",這里的字符串type表示了一個對象類型][1]
function type(obj) { var toString = Object.prototype.toString; var map = { '[object Boolean]' : 'boolean', '[object Number]' : 'number', '[object String]' : 'string', '[object Function]' : 'function', '[object Array]' : 'array', '[object Date]' : 'date', '[object RegExp]' : 'regExp', '[object Undefined]': 'undefined', '[object Null]' : 'null', '[object Object]' : 'object' }; return map[toString.call(obj)];}
實現deepClone
對于非引用值類型的數值,直接賦值,而對于引用值類型(object)還需要再次遍歷,遞歸賦值。
function deepClone(data) { var t = type(data), o, i, ni; if(t === 'array') { o = []; }else if( t === 'object') { o = {}; }else { return data; } if(t === 'array') { for (i = 0, ni = data.length; i < ni; i++) { o.push(deepClone(data[i])); } return o; }else if( t === 'object') { for( i in data) { o[i] = deepClone(data[i]); } return o; }}
這里有個點大家要注意下,對于function類型,博主這里是直接賦值的,還是共享一個內存值。這是因為函數更多的是完成某些功能,有個輸入值和返回值,而且對于上層業務而言更多的是完成業務功能,并不需要真正將函數深拷貝。
但是function類型要怎么拷貝呢?
其實博主只想到了用new來操作一下,但是function就會執行一遍,不敢想象會有什么執行結果哦!o( 主站蜘蛛池模板: 南昌县| 偏关县| 琼结县| 丰城市| 买车| 三台县| 班戈县| 合江县| 余江县| 武安市| 永顺县| 河西区| 南乐县| 南溪县| 昌黎县| 凤阳县| 宽甸| 徐州市| 杨浦区| 宁波市| 顺平县| 衡阳市| 三亚市| 惠水县| 新泰市| 酉阳| 东阿县| 吉隆县| 静海县| 潍坊市| 汝州市| 盐津县| 嵩明县| 醴陵市| 阳山县| 怀化市| 光山县| 固阳县| 玉龙| 龙岩市| 玛曲县|