解讀經典面試題的深拷貝和淺拷貝


以前我理解的淺拷貝就是賦值,深拷貝就是賦址,其實這么理解是錯誤的

對於基本類型來說淺拷貝就是賦值,

對於引用類型來說(obj,arr等),淺復制是對對象地址的復制,並沒有開辟新的棧,也就是復制的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另一個對象的屬性也會改變,而深復制則是開辟新的棧,兩個對象對應兩個不同的地址,修改一個對象的屬性,不會改變另一個對象的屬性

說白了就是淺拷貝都是相同的內存地址,你的值變了 我也跟到變,

深拷貝呢就是你變你的,我們地址都不一樣的,你變了關我屁事

深復制實現代碼如下:
可以從兩個方法進行解決。
https://www.zhihu.com/question/23031215

第二條評論

 componentDidMount(){
        /* let a={age:25}
        let b=a
        b.age=30
        console.log(a);//30 淺拷貝 只是復制的地址 指向的都是同一個內存地址,b改變,a也跟着改變 */

        // 深拷貝(拷貝的對象屬性值里面沒有引用類型(對象等等))
       /*  let a={
            age:25
        }
        let b=Object.assign({},a)
        b.age=27
        console.log(b,'222222')//27
        console.log(a,'aaaa')//25 */
// 這樣一看對的噢可以實現深拷貝,但是如果a對象中屬性值是對象的話,拷貝的是地址,Object.assign所以並不是深拷貝。
        /* let a={
            age:25,
            status:{
                name:'大哥'
            }
        }
        let b=Object.assign({},a)
        b.age=27
        b.status.name='小弟'
        console.log(b,'222222')//27,name打印是小弟
        console.log(a,'aaaa')//25,name打印是小弟  */
// 深拷貝 實現方式的話常用的兩種JSON.parse(JSON.stringify(object)),該方法也是有局限性的
        let a = {
            age:25,
            status:{
                name:'大哥'
            }
        }
        let b = JSON.parse(JSON.stringify(a))
        a.status.name = '小弟'
        console.log(b.status.name) // '大哥'
        console.log(a.status.name) // '小弟'
        // 方法二  lodash 的深拷貝函數
        
        
     } 
   

  

還有一種實現深拷貝的方法  就是  lodash里面的

_.cloneDeep

 

還有就是自己寫的函數實現深度拷貝,改變原型

 

 Object.prototype.clone = function() {
            // Handle null or undefined or function
            if (null == this || "object" != typeof this)
                return this;
            // Handle the 3 simple types, Number and String and Boolean
            if(this instanceof Number || this instanceof String || this instanceof Boolean)
                return this.valueOf();
            // Handle Date
            if (this instanceof Date) {
                var copy = new Date();
                copy.setTime(this.getTime());
                return copy;
            }
            // Handle Array or Object
            if (this instanceof Object || this instanceof Array) {
                var copy = (this instanceof Array)?[]:{};
                for (var attr in this) {
                    if (this.hasOwnProperty(attr))
                        copy[attr] = this[attr]?this[attr].clone():this[attr];
                }
                return copy;
            }
            throw new Error("Unable to clone obj! Its type isn't supported.");
        }
        let a={
            name:'大哥',
            age:{
                ages:27
            }
        }
        let b=a.clone()
       

        b.name='小弟'
        console.log(a,'333')//大哥
        console.log(b,'333')//小弟

 

 還可以自己寫一個函數,適用於大部分對象的深度復制(Deep Clone)。

function clone(obj) {
            // Handle the 3 simple types, and null or undefined or function
            if (null == obj || "object" != typeof obj) return obj;
        
            // Handle Date
            if (obj instanceof Date) {
                var copy = new Date();
                copy.setTime(obj.getTime());
                return copy;
            }
            // Handle Array or Object
            if (obj instanceof Array | obj instanceof Object) {
                var copy = (obj instanceof Array)?[]:{};
                for (var attr in obj) {
                    if (obj.hasOwnProperty(attr))
                      copy[attr] = clone(obj[attr]);
                }
                return copy;
            }
            throw new Error("Unable to clone obj! Its type isn't supported.");
        }
        let a = {
            age:25,
            status:{
                name:'大哥'
            }
        }
        let b = clone(a)
        a.status.name = '小弟'
        console.log(b) // '大哥'
        console.log(a) // '小弟'

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM