javascript基础学习系列四百七十四:合并对象

JavaScript 开发者经常觉得“合并”(merge)两个对象很有用。更具体地说,就是把源对象所有的
本地属性一起复制到目标对象上。有时候这种操作也被称为“混入”(mixin),因为目标对象通过混入
源对象的属性得到了增强。
ECMAScript 6 专门为合并对象提供了Object.assign()方法。这个方法接收一个目标对象和一个
或多个源对象作为参数,然后将每个源对象中可枚举(Object.propertyIsEnumerable()返回true)
和自有(Object.hasOwnProperty()返回true)属性复制到目标对象。以字符串和符号为键的属性
会被复制。对每个符合条件的属性,这个方法会使用源对象上的[[Get]]取得属性的值,然后使用目标
对象上的[[Set]]设置属性的值。
let dest, src, result;
/**

  • 简单复制
    /
    dest = {};
    src = { id: ‘src’ };
    result = Object.assign(dest, src);
    // Object.assign 修改目标对象
    // 也会返回修改后的目标对象
    console.log(dest === result); // true
    console.log(dest !== src); // true
    console.log(result); // { id: src }
    console.log(dest); // { id: src }
    /
    *
  • 多个源对象
    /
    dest = {};
    result = Object.assign(dest, { a: ‘foo’ }, { b: ‘bar’ });
    console.log(result); // { a: foo, b: bar }
    /
    *
  • 获取函数与设置函数
    /
    dest = {
    set a(val) {
    console.log(Invoked dest setter with param ${val});
    }
    };
    src = {
    get a() {
    console.log(‘Invoked src getter’);
    return ‘foo’;
    }
    };
    Object.assign(dest, src);
    // 调用src 的获取方法
    // 调用dest 的设置方法并传入参数"foo"
    // 因为这里的设置函数不执行赋值操作
    // 所以实际上并没有把值转移过来
    console.log(dest); // { set a(val) {…} }
    Object.assign()实际上对每个源对象执行的是浅复制。如果多个源对象都有相同的属性,则使
    用最后一个复制的值。此外,从源对象访问器属性取得的值,比如获取函数,会作为一个静态值赋给目
    标对象。换句话说,不能在两个对象间转移获取函数和设置函数。
    let dest, src, result;
    /
    *
  • 覆盖属性
    /
    dest = { id: ‘dest’ };
    result = Object.assign(dest, { id: ‘src1’, a: ‘foo’ }, { id: ‘src2’, b: ‘bar’ });
    // Object.assign 会覆盖重复的属性
    console.log(result); // { id: src2, a: foo, b: bar }
    // 可以通过目标对象上的设置函数观察到覆盖的过程:
    dest = {
    set id(x) {
    console.log(x);
    }
    };
    Object.assign(dest, { id: ‘first’ }, { id: ‘second’ }, { id: ‘third’ });
    // first
    // second
    // third
    /
    *
  • 对象引用
    /
    dest = {};
    src = { a: {} };
    Object.assign(dest, src);
    // 浅复制意味着只会复制对象的引用
    console.log(dest); // { a :{} }
    console.log(dest.a === src.a); // true
    如果赋值期间出错,则操作会中止并退出,同时抛出错误。Object.assign()没有“回滚”之前
    赋值的概念,因此它是一个尽力而为、可能只会完成部分复制的方法。
    let dest, src, result;
    /
    *
  • 错误处理
    */
    dest = {};
    src = {
    a: ‘foo’,
    get b() {
    // Object.assign()在调用这个获取函数时会抛出错误
    throw new Error();
    },
    c: ‘bar’
    };
    try {
    Object.assign(dest, src);
    } catch(e) {}
    // Object.assign()没办法回滚已经完成的修改
    // 因此在抛出错误之前,目标对象上已经完成的修改会继续存在:
    console.log(dest); // { a: foo }
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值