0
点赞
收藏
分享

微信扫一扫

javascript中赋值、浅拷贝、深拷贝的区别及实例详解

赋值

let a={
    name:'xiaoming',
    age:21,
    grade:{
        language:60,
        math:81,
        english:99,
        science:94
    },
}
let b=a
b.name='xiaowang'
b.grade.language=90
console.log('a',a)
console.log('b',b)


结果分析:对象b和对象a指向同一地址,无论哪个对象发生改变,另外一个对象都会联动变化.

浅拷贝

ES6中有个浅拷贝的方法Object.assign(target, ...sources)。
let a = {
    name: '小明', 
    age: 21,
    grade: {
        language: 78,
        math: 81,
        english: 99,
        science: 94
    },
}
let b = {}
Object.assign(b,a)
b.name = '小花' 
b.grade.english = 9 
console.log('a', a)
console.log('b', b)

结果分析:
b对象改变 name的值和grade对象,a对象只有grade对象的值发生改变,name未受影响。
因为,name是基本类型,b改变自身值,a 不会改变;而grade是一个对象,为引用类型,b拷贝的是该对象的地址,与a指向同一个地址,所以b改变grade对象的值时,a也发生变化。

深拷贝

实现方式

1、JSON.parse(JSON.stringify())

原理

缺点

2、手写递归方法
/**
 * 深拷贝
 * @param {Object} obj 要拷贝对象
 */
function deepClone(obj = {}) {
    if (typeof obj !== 'object' || obj == null) {
        // 不是对象,或者是null
        return obj
    }
    //初始化返回结果
    let result
    if (obj instanceof Array) {
        result =[]
    }else{
        result = {}
    }
    for (const key in obj) {
        //保证key不是原型的属性
        if (obj.hasOwnProperty(key)) { 
            //递归调用!!
            result[key] = deepClone(obj[key])
        }
    }
    //返回结果
    return result
}

结果分析:b对象改变 name的值和grade对象,a均未受到影响,
以为b跟a不共享内存地址,是从堆内存中开辟一个新的区域存放的新对象。

举报

相关推荐

0 条评论