JS數(shù)據(jù)類型思維導(dǎo)圖:
深拷貝與淺拷貝是針對(duì)引用數(shù)據(jù)類型而言,可分下面幾種:
一 JSON.parse(JSON.stringify)深拷貝的局限
1 可以用這個(gè)技巧進(jìn)行數(shù)據(jù)對(duì)象或數(shù)組的拷貝
2 如果被拷貝的對(duì)象中有function摹蘑,則拷貝之后的對(duì)象就會(huì)丟失這個(gè)function
3 如果被拷貝的對(duì)象中有正則表達(dá)式鹃两,則拷貝之后的對(duì)象正則表達(dá)式會(huì)變成Object
二 返回一個(gè)數(shù)組或者對(duì)象的淺拷貝:??Array.prototype.slice()和Array.prototype.concat()嚷节;ES6數(shù)組的解構(gòu)賦值
var o1 = ['darko', {age:22}];
var o2 = o1.slice();// 根據(jù)Array.prototype.slice()的特性啊犬,這里會(huì)返回一個(gè)o1的淺拷貝對(duì)象
console.log(o1 === o2);// => false剖效,說明o2拷貝的是o1的一個(gè)實(shí)例
o2[0] ='lee';
console.log(o1[0]);// => "darko" o1和o2內(nèi)部包含的基本類型值嫉入,復(fù)制的是其實(shí)例焰盗,不會(huì)相互影響
o2[1].age =23;
console.log(o1[1].age);// =>23 o1和o2內(nèi)部包含的引用類型值,復(fù)制的是其引用咒林,會(huì)相互影響
三 深淺拷貝實(shí)現(xiàn):
1 淺拷貝實(shí)現(xiàn):
??function?shallowClone(source)?{
????if?(!source?||?typeof?source?!==?'object')?{
??????throw?new?Error('error?arguments');
????}
????var?targetObj?=?source.constructor?===?Array???[]?:?{};
????for?(var?keys?in?source)?{
??????if?(source.hasOwnProperty(keys))?{
????????targetObj[keys]?=?source[keys];
??????}
????}
????return?targetObj;
??}
2 深拷貝實(shí)現(xiàn):
function deepClone(source){
? if(!source || typeof source !== 'object'){
? ? throw new Error('error arguments', 'shallowClone');
? }
? var targetObj = source.constructor === Array ? [] : {};
? for(var keys in source){
? ? ? if(source.hasOwnProperty(keys)){
? ? ? ? if(source[keys] && typeof source[keys] === 'object'){
? ? ? ? ? targetObj[keys] = source[keys].constructor === Array ? [] : {};
? ? ? ? ? targetObj[keys] = deepClone(source[keys]);
? ? ? ? }else{
? ? ? ? ? targetObj[keys] = source[keys];
? ? ? ? }
? ? ? }
? }
? return targetObj;
}
// test example
var o1 = {
? arr: [1, 2, 3],
? obj: {
? ? key: 'value'
? },
? func: function(){
? ? return 1;
? }
};
var o3 = deepClone(o1);
console.log(o3 === o1); // => false
console.log(o3.obj === o1.obj); // => false
console.log(o2.func === o1.func); // => true