js学習ノート:レプリカ&レプリカ


オブジェクトの複製とは、一つのオブジェクトを元にして同じオブジェクトを生成することです.しかし、javascriptでは、単純な割当文を使用して、元のオブジェクトの参照の一つとして実現され、いずれかのオブジェクト属性方法の変更は、他の属性方法に影響を与えます.
浅いコピー
元のオブジェクトの各属性だけをコピーして、元のオブジェクト属性で参照した他のオブジェクトをコピーしないと、新しいオブジェクトと元のオブジェクトの属性が参照されるのはアドレスです.つまり、ソースオブジェクトの属性値がオブジェクトへの参照であれば、その参照値だけをコピーします.
  • 配列であれば、配列のいくつかの方法を使用してもよく、参照しないときには、浅いコピーの効果を達成することができます.
    var arr = ['old', 1, true, null, undefined];
    
    var newArr = arr.concat();
    var newArr2 = arr.slice();
  • 一般対象:
  • function shadowCopy(src) {
      var dst = src instanceof Array?[]:{};
      for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
          dst[prop] = src[prop];
        }
      }
      return dst;
    }
    
    var obj = {
        a:2,
        b:{c:3}
    };
    
    var shadowObj = shadowCopy(obj);
    
    shadowObj.b == obj.b;  //true
    浅いコピーに対して、新しいオブジェクトと元のオブジェクトは同じオブジェクトを参照することができます.
  • ES 6の増加方法Object.assign()は、オブジェクトの浅いコピーにも使用され得る:
  • var copy = Object.assign({}, obj);
    Object.assignメソッドは、ソースオブジェクト自体をコピーし、列挙可能な属性を対象オブジェクトにのみ適用します.
    深くコピー
    浅いコピーを元に、コピーするオブジェクトを参照するオブジェクトもコピーしました.したがって、再帰的に、上の浅いコピーを改善します.
    function deepCopy(src){
        var dst = {};
        for(prop in src){
            if(src.hasOwnProperty(prop)){
                if(typeof src[prop] == "object"){
                    dst[prop] = deepCopy(src[prop]);
                }else{
                    dst[prop] = src[prop];
                }
            }
        }
        return dst;
    }
    var obj = {
        a:2,
        b:{
            c:3,
            d:{
                e:4
            }
        }
    };
    
    var deepObj = deepCopy(obj);
    
    deepObj.b == obj.b;  //false
    deepObj.b.d == obj.b.d;  //false
    深度コピーは、元のオブジェクトの各属性を1つずつコピーするだけでなく、元のオブジェクトの各属性に含まれるオブジェクトも順次、深度コピーを用いて新しいオブジェクトに再帰的にコピーすることができます.
    深度コピーを実現するには他にも多くの方法があります.
  • JSON方法
  • var cloneObj = JSON.parse(JSON.stringify(obj));
  • jQuery.exted()
  • jQuery.extend([deep], target, object1, [objectN])
    この方法は、1つ以上の他のオブジェクトでオブジェクトを拡張し、拡張されたオブジェクトを返します.
    最初のdeepパラメータは、深いコピーかそれとも浅いコピーかを指定します.trueなら深度コピーです.
  • コピー各タイプの値
  • function clone(src){
        var target;
        if(typeof src != "object"){
            return src;
        }
        target = Array.isArray(src)?[]:{};
        for(var prop in src){
            if(Object.prototype.hasOwnProperty.call(src,prop)){
                target[prop] = clone(src[prop]);
            }
        }
        return target;
    }