js數據存儲

1. 編碼

(1)ASCII碼錶:128剛好7個二進制位(0~127),依次爲基本的控制字符、數字48......57,英文字母97......65,標點符號。一個英文字母、數字、標點符號(英文)都是1個字節。

(2)雙字節字符:與ASCII碼重合的都是1個字節,其餘的獨有字符2個字節(gb2312)。

(3)Unicode編碼:使用2個字節表示1個字符(任何字符)。

(4)utf-8編碼:統一轉換格式,與ASCII重合部分使用1個字節,漢字使用3個字節。

<script type="text/javascript">
    var num; // 只聲明,不開闢內存	
    var num = 123; // 科學計數法存儲,4個字節
    var num = [1, 2, 3]; // 將數據存儲在一個單獨的內存中,該數組的地址給變量存起來
    var num = '123'; // 4字節,3個字節有用
</script>

PS:1個字節byte是8個二進制位,字word是一個字符。

2. 值類型與引用類型的存儲

(1)內存邏輯結構

(2)賦值:值類型賦值的存儲特點,將變量內的數據全部拷貝一份,存儲給新的變量,其特點是在內存中有兩個數據副本,即兩個變量兩個數據;var o = { name: '張三' }; var obj = o; 引用類型賦值就是將變量o中存儲的數據(引用)拷貝一份,然後將該數據賦值給obj,內存中只有1份數據,利用obj修改的name屬性會影響到o中的name屬性,即兩個變量一個數據。

(3)作爲函數參數:函數在調用時,首先將參數中的數據拷貝一份,跳轉到函數定義中(函數體),在此之前完成了參數的賦值;值類型作爲函數參數傳遞時,函數內與函數外是兩個不同的變量,僅僅是值相等而已;引用類型作爲函數參數傳遞時,函數內與函數外是兩個不同的變量,但是指向同一個對象。

<script>
    var o = { name: 'Karry', age: 19, gender: 'man'};
    o.copy = function( arg ) {
        for( var k in this ) {
            arg[k] = this[k];
        }
    };
    // var p1; // copy結果爲undefined,必須引用類型(對象)作爲參數傳遞
    var p1 = {}; // copy結果成功
    o.copy( p1 ); // p1和arg指向同一個對象
    console.log(p1);
</script>

3. 深拷貝與淺拷貝

(1)概念:如果拷貝的時候,將數據的所有引用結構都拷貝一份,那麼數據在內存中獨立就是深拷貝;如果拷貝的時候,只針對當前對象的屬性進行拷貝,那麼就是淺拷貝。

<script>
    var car = { name: '法拉利' };
    var p = { name: '張三', age: 19, car: car };

    // var pCopy = p; // 這個不是拷貝,沒有對對象做任何拷貝行爲
    var pCopy = {}; // 淺拷貝的代碼實現
    pCopy.name = p.name;
    pCopy.age = p.age;
    pCopy.car = p.car;

    var pCopy = {}; // 深拷貝的代碼實現
    pCopy.name = p.name;
    pCopy.age = p.age;
    pCopy.car = {};
    pCopy.car.name = p.car.name;
</script>

(2)代碼的封裝

<script>
    // 淺拷貝代碼的封裝
    var car2 = { name: '法拉利' };
    var p2 = {
        name: 'Karry',
        age: 19,
        car2: car2,
        copy: function () { // 將當前對象拷貝一份
            var temp = {}; // 創建對象
            for ( var k in this ) {
                temp[ k ] = this[ k ]; // 複製屬性,在copy中使用this表示當前對象
            }
            return temp; // 返回新對象
        }
    }
    var p2Copy = p2.copy();
    p2.name = 'wang'; // p2Copy不改變
    p2.car2.name = '寶馬'; // p2、p2Copy均改變

    // 深拷貝代碼的封裝
    var deepCopy = function() { // 保證所有對象中都有copy方法
        var temp = {}; // 創建對象
        for ( var k in this ) {
            if ( typeof this[k] === 'object' ) { // 拷貝屬性,判斷是引用類型則需要深拷貝
                temp[k] = this[k].deepCopy();
            } else {
                temp[k] = this[k];
            }
        }
        return temp;// 返回對象
    }
    var car3 = { name: '法拉利' };
    var p3 = { name: '張三', car3: car3 };
    car3.deepCopy = deepCopy;
    p3.deepCopy = deepCopy;

    var newP3 = p3.deepCopy();
    p3.name = 'Karry';
    p3.car3.name = '奔馳'; // p3改變、newP3不改變
</script>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章