参考:http://qianduanblog.com/post/js-learning-30-object-clone-copy.html
基本数据类型:Boolean/Number/String
var a='a'; var b; b=a; b='b'; console.log(a); console.log(b);
基本数据类型的克隆是对象的直接克隆,两者只是值得传递,克隆之后两者没有联系
引用数据类型:Array/Object/Function
数组的克隆
var a = [1,2]; var b; b = a; b[2] = 3; console.log(a); // {1,2,3}
这种普通的克隆可以看到两者控制的是同一个对象,这是引用类型的特点。可以通过循环来克隆无关的两组数组。
var a = [1,2]; var b = []; var i = 0; var j = a.length; for (;i<j;i++) { b[i] = a[i]; } b.push(3); console.log(b); // {1,2,3} console.log(a); // {1,2}
因为数组也是对象,所以的对象的克隆和数组是一样的
var a = {1:'one',2:'two'} var b = {}; for(var i in a) { b[i] = a[i]; } console.log(b); // Object {1: "one", 2: "two"} b[3] = 'three'; console.log(b); // Object {1: "one", 2: "three"} console.log(1); // Object {1: "one", 2: "two"}
函数的克隆比较特殊:函数的克隆,使用“=”符号就可以了,并且在改变克隆后的对象,不会影响克隆之前的对象,因为克隆之后的对象会单独复制一次并存储实际数据的,是真实的克隆。
var x=function(){alert(1);}; var y=x; y=function(){alert(2);}; // function(){alert(1);}; alert(x); // y=function(){alert(2);}; alert(y);
完整的对象克隆:
完整的对象克隆需要对参数进行类型判断,是个综合的应用。
function isArray(arr) { return Object.prototype.toString.call(arr) === "[object Array]"; } function isPlain(obj){ return Object.prototype.toString.call(obj) === "[object Object]"; } function cloneObject(src) { var result = src; if(!src || src instanceof Number || src instanceof String || src instanceof Boolean) { return result; }else if(isArray(src)) { var result = []; var resultLen = 0; for(var i = 0,len = src.length;i < len; i++) { result[resultLen++] = cloneObject(src[i]); } }else if (isPlain(src)) { result = []; for (var i in src) { if (src.hasOwnProperty(i)) { result[i] = cloneObject(src[i]); } } } return result; } // 测试用例 var srcObj = { a: 1, b: { b1: ["hello", "hi"], b2: "JavaScript" } }; var abObj = srcObj; var tarObj = cloneObject(srcObj); srcObj.a = 2; srcObj.b.b1[0] = "Hello"; console.log(abObj.a); console.log(abObj.b.b1[0]); console.log(tarObj.a); // 1 console.log(tarObj.b.b1[0]); // "hello"