关于javascript:Objectassign更新对象

Object.assign()

Object.assign() 办法用于将所有可枚举属性的值从一个或多个源对象调配到指标对象。它将返回指标对象。
Object.assign 办法只会拷贝源对象本身的并且可枚举的属性到指标对象。该办法应用源对象的[[Get]]和指标对象的[[Set]],所以它会调用相干 getter 和 setter。因而,它调配属性,而不仅仅是复制或定义新的属性。如果合并源蕴含getter,这可能使其不适宜将新属性合并到原型中。
为了将属性定义(包含其可枚举性)复制到原型,应应用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。
String类型和 Symbol 类型的属性都会被拷贝。

更新对象

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target); // { a: 1, b: 4, c: 5 }

console.log(returnedTarget); // { a: 1, b: 4, c: 5 }

复制一个对象

const obj = { a: 1, b: 2, c: 3 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1, b: 2, c: 3 }

合并对象

const obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };

const obj = Object.assign(obj1, obj2, obj3);
console.log(obj1); // { a: 1, b: 2, c: 3 }
console.log(obj);  // { a: 1, b: 2, c: 3 }, 指标对象本身也会扭转。

拷贝

Object.assign拷贝的属性是有限度的,只拷贝源对象的本身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。


Object.assign({b: 'c'},
    Object.defineProperty({}, 'invisible', {
        enumerable: false,
        value: 'hello'
    })
)
// { b: 'c' }

属性名为 Symbol 值的属性,也会被Object.assign拷贝

Object.assign({ a: 'b', b: 'c'}, { [Symbol('c')]: 'd' })
// { a: 'b', b: 'c', Symbol(c): 'd' }

总结

1.为对象增加属性

class Point {
    constructor(x, y) {
        Object.assign(this, {x, y});
    }
}

2.为对象增加办法

Object.assign(mainContent.prototype, {
    oneMethod(arg1, arg2) {
    },
    anotherMethod() {
    }
});

等同于上面的写法

mainContent.prototype.oneMethod = function (arg1, arg2) {
};
mainContent.prototype.anotherMethod = function () {
};

3.复制一个对象

const obj = { a: 1, b: 2, c: 3 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1, b: 2, c: 3 }

4.合并对象

const obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };

const obj = Object.assign(obj1, obj2, obj3);
console.log(obj1); // { a: 1, b: 2, c: 3 }
console.log(obj);  // { a: 1, b: 2, c: 3 }, 指标对象本身也会扭转。

5.为属性指定默认值

const DEFAULTS = {
    logLevel: 0,
    outputFormat: 'html'
};
function processContent(options) {
    let options = Object.assign({}, DEFAULTS, options);
}

MDN

拷贝拜访器

const obj = {
  foo: 1,
  get bar() {
    return 2;
  }
};

let copy = Object.assign({}, obj); 
console.log(copy); // { foo: 1, bar: 2 } copy.bar的值来自obj.bar的getter函数的返回值

// 上面这个函数会拷贝所有自有属性的属性描述符
function completeAssign(target, ...sources) {
  sources.forEach(source => {
    let descriptors = Object.keys(source).reduce((descriptors, key) => {
      descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
      return descriptors;
    }, {});

    // Object.assign 默认也会拷贝可枚举的Symbols
    Object.getOwnPropertySymbols(source).forEach(sym => {
      let descriptor = Object.getOwnPropertyDescriptor(source, sym);
      if (descriptor.enumerable) {
        descriptors[sym] = descriptor;
      }
    });
    Object.defineProperties(target, descriptors);
  });
  return target;
}

copy = completeAssign({}, obj);
console.log(copy);
// { foo:1, get bar() { return 2 } }

Object.assign()更新对象%E6%9B%B4%E6%96%B0%E5%AF%B9%E8%B1%A1.md)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理