【ES6】Object.assign方法与深浅拷贝

文章目录

  • 一、Object.assign
  • 二、用法详解
    • 1.Object.assign浅拷贝
    • 2. 实现深拷贝
    • 3. 自定义函数实现深拷贝
  • 总结


一、Object.assign

  • Object.assign 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
  • Object.assign 方法的第一个参数是目标对象,后面的参数都是源对象。 注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
  • Object.assign 拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性( enumerable: false )。即Object.assign 方法实行的是浅拷贝,而不是深拷贝。
    也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

二、用法详解

1.Object.assign浅拷贝

对于基本数据类型,遇到同名属性则直接将其替换。对于引用数据类型,直接把指向的地址替换为目标地址,而它本有的原始属性会丢失掉。

const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2

上面代码中,源对象 obj1 的 a 属性的值是一个对象, Object.assign 拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。

let target = {
    a: {
        b: {
            c: 1
        },
        e: 4,
        f: 5,
        g: 6
    }
}
let source = {
    a: {
        b: {
            c: 1
        },
        e: 2,
        f: 3
    }
}
Object.assign(target, source)
console.log(target)
// 结果中,没有g这个属性
let a = 5
let b = a //b指向a的地址
a = 6
console.log(a, b)
// 6 5

let obj1 = {
    name: 'kakaDorothy',
    age: 20
}
let obj2 = obj1 //指向同一块内存地址
obj1.age = 18
console.log(obj1)
//age为18
console.log(obj2)
//age为18

2. 实现深拷贝

let obj1 = {
    name: 'kakaDorothy',
    age: 20
}
//'{"a": "hello", "b": "world"}'
// 使用JSON

//把JSON字符串转换为对象
let obj = JSON.parse('{"a": "hello", "b": "world"}')
console.log(obj)
// {a: "hello", b: "world"}

// 把对象转换成JSON字符串
let str = JSON.stringify(obj)
console.log(str)
// {"a": "hello", "b": "world"}

// 实现深拷贝
let str = JSON.stringify(obj1)
let obj2 = JSON.parse(str)
obj1.age = 18
console.log(obj2)
// {name: "kakaDorothy",age: 20}, age不会改变

3. 自定义函数实现深拷贝

// 检查类型
let checkType = data => {
// typeof无法分辨出Object和Array,常使用Object.prototype.toString方法来判断
// toString.call(data),将data作为参数传进去判断,会返回一个数组[Object Array],数组里面包含data的类型
// 使用slice方法切割掉[Object ,所以是从8开始;-1将]切割掉
    return Object.prototype.toString.call(data).slice(8, -1)
}
checkType({})

let deepClone = target => {
    let targetType = checkType(target)
    let result
    if (targetType === 'Object') {
        result = {}
    } else if (targetType === 'Array') {
        result = []
    } else {
        return target
    }
    for (let i in target) {
        let value = target[i]
        let valueType = checkType(value)
        if (valueType === 'Object' || valueType === 'Array') {
            result[i] = deepClone(value) // 递归
        } else {
            result[i] = value
        }
    }
    return result
}
// let arr1 = [1, 2, {age: 18}]
// let arr2 = deepClone(arr1)
// arr2[2].age = 20
// console.log(arr1)

let obj1 = {
    name: 'kakaDorothy',
    hobby: ['coding', 'eating']
}
let obj2 = deepClone(obj1)
obj2.hobby[0] = 'sleeping'
console.log(obj1)
console.log(obj2)

总结

Object.assign 方法有很多用处:
(1)为对象添加属性
(2)为对象添加方法
(3)克隆对象
(4)合并多个对象 将多个对象合并到某个对象
(5)为属性指定默认值

你可能感兴趣的:(ES6,javascript,开发语言,ecmascript)