使用递归进行深拷贝
http://lingyu.wang/2014/03/20/js-interview-1/
Object.prototype.deepClone = function() { var isArray = function(obj) { return Object.prototype.toString.call(obj) === "[object Array]"; }; var isObj = function(obj) { return Object.prototype.toString.call(obj) === "[object Object]"; }; var deepClone = Object.prototype.deepClone; var obj = this.isArray ? [] : {}; for (var prop in this) { if (isObj(this[prop])) { this[prop].deepClone(); } obj[prop] = this[prop]; } return obj; };
这个代码是有些问题的 关键就在于这个判断 if (isObj(this[prop])) {
运行下面 就发现 rs 也被改了
var arr = [[1,2,3],4,5,6]; var change = arr[0]; var rs = arr.deepClone(); change[0] = 'change'; console.log(rs);
略微修改一下
Object.prototype.deepClone = function() { var isArray = function(obj) { return Object.prototype.toString.call(obj) === "[object Array]"; }; var isObj = function(obj) { return Object.prototype.toString.call(obj) === "[object Object]"; }; var deepClone = Object.prototype.deepClone; var obj = isArray(this) ? [] : {}; // 深拷贝关键点: 对于非简单类型的对象 就是创建一个新对象然后将值一个个的copy过来 //PS 数组的遍历也是同样可以使用 for in 的 只不过for in会把该数组的增加的一些对象也遍历出来 所以需要使用 hasOwnProperty 来判断 这样子都是数组中的元素了 // 本例子中如果不加上 hasOwnProperty 遍历出的数组还有一个 deepClone for (var prop in this) { if (this.hasOwnProperty(prop)) { console.log(prop + '---' + this[prop]); if (isObj(this[prop]) || isArray(this[prop])) { obj[prop] = this[prop].deepClone(); }else{ obj[prop] = this[prop]; } } } return obj; }; var arr = [ [1, 2, 3], 4, 5, 6 ]; var rs = arr.deepClone(); var change = arr[0]; change[0] = 'change'; console.log(rs);
转载http://mao.li/javascript/javascript/
window.onload = function() { testCons(); Object.prototype.Clone = function() { var objClone; if (this.constructor == Object) { objClone = new this.constructor(); } else { // objClone=new this.constructor(this.valueOf()); objClone = this.valueOf();//似乎这样也没错? } for (var key in this) { if (objClone[key] != this[key]) { if (typeof(this[key]) == 'object') { objClone[key] = this[key].Clone(); } else { objClone[key] = this[key]; } } } objClone.toString = this.toString; objClone.valueOf = this.valueOf; return objClone; } var obj1 = { key1: 1, key2: { key21: 21, key22:"22", key23:{ key221:221 } } } obj2 = obj1.Clone(); console.log(obj2); console.log(typeof obj2.key2.key21); }
关于new this.consturctor(this.valueOf());
话说之前还木有见到过这样的写法 感觉这里就是构造函数创建对象
function testCons() { var num = 5; console.log(num.constructor(6)); //6 console.log(typeof num.constructor(6)); //number console.log(num.constructor);//function Number() { [native code] } console.log(num.constructor==Number);//true n=new num.constructor(6); console.log(typeof n); //object 你看typeof来判断类型很笼统 注意和不用new的区别 这个和js包装对象有关 console.log(n.constructor);//function Number() { [native code] } console.log(n.constructor==Object); //false //因此用constructor来判断类型是最合适不过的 function Person(name) { this.name = name; } p1 = new Person('fgh'); console.log(p1.constructor == Person); //true p2 = new p1.constructor('bnmn'); console.log(p2.name); //bnmn //两者一致 console.log(Person); console.log(p2.constructor); }
js包装对象
//js包装对象 var a=Number(5); console.log(typeof a);//number console.log(a.constructor);//function Number() { [native code] var b=new Number(6); console.log(typeof b);//object console.log(b.constructor);//function Number() { [native code] } var num=5; num2=new num.constructor(6); console.log(num.constructor==Number);//true 所以这里new num.constructor 相当于Number(6) console.log(num.constructor);//function Number() { [native code] } console.log(typeof num2); //object