JS 深拷贝

使用递归进行深拷贝

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

 

 

 

posted @ 2014-04-18 13:41  cart55free99  阅读(226)  评论(0编辑  收藏  举报