zoukankan      html  css  js  c++  java
  • JS 深拷贝

    要实现深复制有很多办法,比如最简单的办法有:
    
    var cloneObj = JSON.parse(JSON.stringify(obj));
    上面这种方法好处是非常简单易用,但是坏处也显而易见,这会抛弃对象的constructor,也就是深复制之后,无论这个对象原本的构造函数是什么,在深复制之后都会变成Object。
    另外诸如RegExp对象是无法通过这种方式深复制的。
    
    所以这里我将介绍一种,我自认为很优美的深复制方法,当然可能也存在问题。如果你发现了我的实现方法有什么问题,请及时让我知道~
    
    先决条件:
    1. 对于任何对象,它可能的类型有Boolean, Number, Date, String, RegExp, Array 以及 Object(所有自定义的对象全都继承于Object)
    2. 我们必须保留对象的构造函数信息(从而使新对象可以使用定义在prototype上的函数)
    
    最重要的一个函数:
    
    Object.prototype.clone = function () {
        var Constructor = this.constructor;
        var obj = new Constructor();
    
        for (var attr in this) {
            if (this.hasOwnProperty(attr)) {
                if (typeof(this[attr]) !== "function") {
                    if (this[attr] === null) {
                        obj[attr] = null;
                    }
                    else {
                        obj[attr] = this[attr].clone();
                    }
                }
            }
        }
        return obj;
    };
    定义在Object.prototype上的clone()函数是整个方法的核心,对于任意一个非js预定义的对象,都会调用这个函数。而对于所有js预定义的对象,如Number,Array等,
    我们就要实现一个辅助clone()函数来实现完整的克隆过程:
    
    /* Method of Array*/
    Array.prototype.clone = function () {
        var thisArr = this.valueOf();
        var newArr = [];
        for (var i=0; i<thisArr.length; i++) {
            newArr.push(thisArr[i].clone());
        }
        return newArr;
    };
    
    /* Method of Boolean, Number, String*/
    Boolean.prototype.clone = function() { return this.valueOf(); };
    Number.prototype.clone = function() { return this.valueOf(); };
    String.prototype.clone = function() { return this.valueOf(); };
    
    /* Method of Date*/
    Date.prototype.clone = function() { return new Date(this.valueOf()); };
    
    /* Method of RegExp*/
    RegExp.prototype.clone = function() {
        var pattern = this.valueOf();
        var flags = '';
        flags += pattern.global ? 'g' : '';
        flags += pattern.ignoreCase ? 'i' : '';
        flags += pattern.multiline ? 'm' : '';
        return new RegExp(pattern.source, flags);
    };
    可能直接定义在预定义对象的方法上,让人感觉会有些问题。但在我看来这是一种优美的实现方式。
      
  • 相关阅读:
    python yield from (一)
    python yield: send, close, throw
    python I/O多路复用 使用http完成http请求
    python I/O复用
    python 进程间通信
    mac 使用express -e ./
    Object.keys使用整理
    MacBook pro管理员变成普通用户无法解锁问题
    MAC应用无法打开或文件损坏的处理方法
    Redis "MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk"问题的解决
  • 原文地址:https://www.cnblogs.com/lbonet/p/7170170.html
Copyright © 2011-2022 走看看