关于javascript:Objectassign更新对象

6次阅读

共计 2490 个字符,预计需要花费 7 分钟才能阅读完成。

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)

正文完
 0