JavaScript中的資料類型分為兩大類:原始類型和物件類型。(1)原始類型包括:數值、字串、布爾值、null、undefined(我們需要複製的主要是前面三個)(2)物件類型包括:對象(Object),函數(Function)、數組(Array)。在複製過程中對這兩類資料類型的處理方式是不一樣的,下面先分別講解兩種資料類型的複製方式。 一、原始類型複製
1、數值的複製
var x=1;var y=x;y=2;console.log(x); //1console.log(y); //2
2、字串的複製
var x="abc";var y=x;y="def";console.log(x); //abcconsole.log(y); //def
3、布爾值的複製
var x = true;var y = x;y=false;console.log(x); //trueconsole.log(y); //false
由於原始類型儲存的是對象的實際資料,因此我們可以通過簡單的複製方式即可得到正確的結果,而且不影響之前的對象。 二、物件類型複製
1、數組的複製
var x = [1,2,3];var y = x;console.log(y); //[1,2,3]y.push(4);console.log(y); //[1,2,3,4]console.log(x); //[1,2,3,4]
物件類型儲存的是對象的引用地址,而把對象的實際內容單獨存放,因為物件類型通常比較龐大,這是資料開銷和記憶體開銷最佳化的手段。因此我們不能像未經處理資料類型一樣簡單的賦值,而應該遍曆資料中的每一個元素,將其中的每一個未經處理資料類型複製過去,做法如下:
var x = [1,2,3];var y = [];for (var i = 0; i < x.length; i++) { y[i]=x[i];}console.log(y); //[1,2,3]y.push(4);console.log(y); //[1,2,3,4]console.log(x); //[1,2,3]
2、對象的複製
參照數組的複製,我們採用同樣的思想進行對象的複製:
var x = {a:1,b:2};var y = {};for(var i in x){ y[i] = x[i];}console.log(y); //Object {a: 1, b: 2}y.c = 3;console.log(y); //Object {a: 1, b: 2, c: 3}console.log(x); //Object {a: 1, b: 2}
3、函數的複製
var x = function(){console.log(1);};var y = x;y = function(){console.log(2);};x(); //1y(); //2
由於函數對象複製之後的對象會單獨複製一次並儲存實際資料,因此並不會影響複製之前的對象。所以採用簡單的複製“=”即可完成複製。 三、通用的對象複製
通過上面的分析,我們知道對於原始類型以及物件類型中的函數是可以直接通過“=”複製來實現複製,而對於對象和數組,則需要遍曆每一個元素,如果元素為對象或數組,則需繼續遍曆,直到為原始類型或函數,則直接通過“=”複製。
function deepClone(obj){ var result; var oClass=isClass(obj); if(oClass==="Object"){ result={}; }else if(oClass==="Array"){ result=[]; }else{ return obj; } for(var key in obj){ var copy=obj[key]; if(isClass(copy)=="Object"){ result[key]=arguments.callee(copy);//遞迴調用 }else if(isClass(copy)=="Array"){ result[key]=arguments.callee(copy); }else{ result[key]=obj[key]; } } return result;}//判斷對象的資料類型function isClass(o){ if(o===null) return "Null"; if(o===undefined) return "Undefined"; return Object.prototype.toString.call(o).slice(8,-1);}