JavaScriptシリーズの深度コピーと浅いコピー

23933 ワード

目次
  • クライテリア
  • コピーと浅いコピー-参照のタイプは、
  • を考慮することができます.
  • 浅いコピー-参照タイプはすべて基本タイプ
  • です.
  • リピート・参照タイプには、参照タイプ
  • が含まれている.
    前言
            ,        。
    
    純粋な美酒の方向に進んでいます.久しぶりにブログを発表しました.仕事の積み重ねが個人のノートに記録されました.この時間は毎日csdnの上で技能の上の知識の点を見て、いくつか文章の博主の文才が面白くて分かりやすいと思います.そして今まで自分のブログを開いて、見るに堪えないです.昔の事は回想してはいけない,未来は期待できるよ.
    深いコピーと浅いコピー-引用のタイプは考えられます.
    明面に浅いコピーはディスク(D:\luudown/demo.doc)のワードファイルを別のアドレスにコピーしたと理解できます.陰では、jsでのデータのコピー操作を指します.jsデータといえば、データの種類を言わなければならないです.基本データの種類と引用データの種類はもう考えられました.どんなタイプのものであれ、まず操作をします.
    var basic = "    ";
    var obj   = {
    	name: "    -Object",
    	child: [1, 2, 3] //     ,          
    };
    console.log(basic); //     
    console.log(obj); // {name: "    -Object", child: Array(3)}
    //             ,              
    var copyBasic = basic;
    var copyObj   = obj;
    console.log(copyBasic); //     
    console.log(copyObj); // {name: "    -Object", child: Array(3)}
    //           (  。。。)
    //     ,  copy   ,       
    copyBasic = "copy    ";
    console.log(basic); //     
    console.log(copyBasic); // copy    
    //   ,  。          ,  obj 
    copyObj.name = "copy    -Object";
    console.log(obj); // {name: "copy    -Object", child: Array(3)}
    console.log(copyObj); // {name: "copy    -Object", child: Array(3)}
    //   , bug。   obj      。。。。
    
    上記の問題が発生したら、どのような問題が発生したのかを考えなければなりません.はい、そうです.データタイプのいたずらです.そのデータのタイプの違いはなぜ起きますか?これはjsの山とスタックをかき集める必要があります.
  • スタックメモリは基本的なデータタイプを格納し、固定サイズがあり、値によってアクセスする.
  • ヒープメモリは参照データタイプを記憶し、固定サイズなし、参照アクセス.
  • 記述:copyObjは、Objスタックのメモリを持つリードに相当する.両方ともこのメモリを操作できます.copyBaicはスタック空間で新たに一つの空間を開発したのに相当します.Baicの値をこの新しい空間にコピーします.両者は直接関係がありません.上は大雅を傷つけず、下は戦場.
    浅いコピー-参照のタイプはすべて基本タイプです.
    この場合、オブジェクトes6 に適用されてもよい.オブジェクトassign()に対してのみ針は、オブジェクトconcat()slice()に対してのみ使用されてもよい.
    一、es 6方式
    var obj = {
    	name: "obj",
    	age: "12"
    };
    var arr = [1, "2", 3];
    // es6  
    var copyObj = {...obj};
    copyObj.name = 'copyObj'; //     
    console.log(obj); // {name: "obj", age: "12"}
    console.log(copyObj); // {name: "copyObj", age: "12"}
    
    var copyArr = [...arr];
    copyArr.push(4); //     
    console.log(arr);  //  [1, "2", 3]
    console.log(copyArr); //  [1, "2", 3, 4]
    
    以上のように、First bloodを叫んで、完璧な首殺.二、assign方式
    var obj = {
    	name: "obj",
    	age: "12"
    };
    var copyObj = Object.assign({}, obj);
    copyObj.name = 'copyObj'; //     
    console.log(obj); // {name: "obj", age: "12"}
    console.log(copyObj); // {name: "copyObj", age: "12"}
    
    ということで、Double killを叫ぶと、両殺して手に入れます.三、concat()とslice()方式
    var arr = [1, "2", 3];
    var copyConcatArr = [].concat(arr);
    copyConcatArr .push(4); //     
    console.log(arr);  //  [1, "2", 3]
    console.log(copyConcatArr); //  [1, "2", 3, 4]
    var copySliceArr = Array.prototype.slice.apply(arr);
    copySliceArr.push(4); //     
    console.log(arr);  //  [1, "2", 3]
    console.log(copySliceArr); //  [1, "2", 3, 4]
    
    以上のように、雄叫びTriple killは、三殺に接続されます.
    深くコピーします.参照の種類には参照の種類があります.
    深コピーはいつ使いますか?
  • データタイプは、基本データタイプ
  • ではありません.
  • コピーの参照タイプには、参照タイプ
  • が含まれている.
    案:JSON.parse():引用タイプに適用されない参照タイプは、undefined、function(この例はまだ列挙されていない)、smbol(この例はまだ列挙されていない)シーンを含む. :一回使うと一生役に立ちます.一、JSON.parse()とJSON.stringifg()
  • 値はundefined
  • を含まない.
    var obj = {
    	name: 'obj',
    	job: ['object', 'array']
    }
    var arr = [1, [arrObj: {name: 'arrObj'}]]; //        
    
    var copyObj = JSON.parse(JSON.stringify(obj));
    copyObj.job.push('null');
    console.log(obj); // {name: "obj", job: Array(2)}
    console.log(copyObj); // {name: "obj", job: Array(3)}
    
    var copyArr = JSON.parse(JSON.stringify(arr));
    copyArr[1][0].arrObj.name = 'copyArrObj';
    console.log(arr[1][0].arrObj); // {name: "arrObj"}
    console.log(copyArr[1][0].arrObj); // {name: "copyArrObj"}
    
    以上、クァルターキルを喚声し、手を四殺します.
  • 値はundefined
  • を含む.
    // undefined
    var arr = [1, 2, {a: undefined}];
    var copyArr = JSON.parse(JSON.stringify(arr));
    console.log(arr); // [1,2,{a:undefined}]
    console.log(copyArr); // [1,2,{}]
    
    上記の通り、Penta killを叫んで、完璧な五殺です.
    二、最終必殺-再帰関数
    function deepCopy(param) {
       //   param        ,             ,        
       if (!param || !(param instanceof Object)) return param;
       //          ;
       var result = Object.prototype.toString.call(param).indexOf('Array') > -1 ? [] : {};
       for (var key in param) {
           //         ,        
           if(!param.hasOwnProperty(key)) continue;
           //                    
           if(typeof param[key] === 'object' && param[key] !== null) {
              resule[key] = deepCopy(param[key]);
           }
           else {
               result[key] = param[key];
           }
       }
       return result;
    };
    
    以上、Legendary killを叫ぶと、あなたは超神です.