js深淺拷貝

js深淺拷貝

什麼是拷貝

  • 所謂的拷貝就是將一個對象複製一份, 獲得另外一個對象, 要求與原有對象如出一轍.
var o1 = { name: 'jim' };
  var o2 = o1;

此時變量中存儲的是引用, 所以有引用的拷貝. 可是沒有對象的拷貝.若是是說深淺拷貝的概念, 這裏沒有拷貝.json

深淺拷貝

  • 若是一個對象與其副本在內存中徹底隔離, 稱之爲深拷貝.
  • 若是對象中沒有引用類型的屬性( 除了方法之外 ), 那麼深淺拷貝是同樣的, 沒有區別.
  • 若是對象中含有引用類型的屬性, 那麼在拷貝的時候沒有將其拷貝一份, 那麼就不是深拷貝.
var o1 = {
            name: 'jim',
            scores: {
                chinese: 90,
                english: 95,
                math: 85
            }
        };
  • 通常狀況, 涉及拷貝的概念時, 使用代碼都是講一個對象的全部屬性遍歷賦值
function copy( obj ) {
            var tmp = {};  // 建立了對象
            for ( var k in obj ) {
                tmp[ k ] = obj[ k ];   // 有與原來對象如出一轍的屬性
            }
            return tmp;
        }
        var o2 = copy( o1 );

該代碼是拷貝一個新對象, 可是該對象的屬性 scores 是共享的, 所以不是深拷貝.數組

實現深拷貝

function deepCopy ( obj ) {
         var tmp = {};  
         for ( var k in obj ) {
            tmp[ k ] = obj[ k ]; 
         }
         return tmp;
    }
    //在這個函數中最關鍵的一步 tmp[ k ] = obj[ k ]
    //因此這裏只須要保證 obj[ k ] 這個賦值是一個深度拷貝的對象便可.
    //注意: 函數的目的是獲得 obj 的深拷貝副本. 所以遞歸一下.

    function deepCopy ( obj ) {
        var tmp = {}, k;
            for ( k in obj ) {
                if ( typeof obj[ k ] === 'object' ) {
                    tmp[ k ] = deepCopy( obj[ k ] );
                } else {
                    tmp[ k ] = obj[ k ];
                }
            }
            return tmp;
        }

        // 若是處理這個對象
        var o3 = {
            name: 'jim',
            scores: [
                90, 
                95,
                85
            ]
        };

        // 該代碼沒法處理數組的狀況
        function deepCopy ( obj ) {
            var tmp = obj.length >= 0 ? 
                        obj instanceof Array ? [] : { length: 0 } : 
                        {}, 
                k;
            for ( k in obj ) {
                if ( typeof obj[ k ] === 'object' ) {
                    tmp[ k ] = deepCopy( obj[ k ] );
                } else {
                    tmp[ k ] = obj[ k ];
                }
            }
            return tmp;
        }

用js原生的json序列化的方式實現對象拷貝

var o4 = JSON.parse(JSON.stringify(o3));

這種方法簡單粗暴 (╯‵□′)╯︵┻━┻ 哈哈哈,好處是很是簡單易用,可是壞處也顯而易見,這會拋棄對象的constructor,也就是深複製以後,不管這個對象本來的構造函數是什麼,在深複製以後都會變成Object。另外諸如RegExp對象是沒法經過這種方式深複製的。函數

相關文章
相關標籤/搜索