Start · Sprachen · JavaScript · Referenz · Object.assign()

Object.assign()

Methode

Die statische Methode <code>Object.assign()</code> kopiert alle enumerable own properties von einem oder mehreren Quellobjekten in ein Zielobjekt und gibt dieses zurück.

Kategorie: method-property

Signatur

Object.assign(target) Object.assign(target, source1) Object.assign(target, source1, source2) Object.assign(target, source1, source2, /* …, */ sourceN)

Beschreibung

Eigenschaften im Zielobjekt werden von Eigenschaften der Quellen überschrieben, wenn sie denselben key haben. Eigenschaften späterer Quellen überschreiben die früherer.

Die Methode Object.assign() kopiert nur enumerable und own Eigenschaften von einem Quellobjekt in ein Zielobjekt. Sie verwendet [[Get]] auf der Quelle und [[Set]] auf dem Ziel, ruft also getter und setter auf. Daher weist sie Eigenschaften zu, statt neue Eigenschaften zu kopieren oder zu definieren. Das kann sie ungeeignet machen, wenn neue Eigenschaften in einen prototype eingefügt werden sollen und die Merge-Quellen getter enthalten.

Um Eigenschaftsdefinitionen (einschließlich ihrer Enumerability) in prototypes zu kopieren, verwende stattdessen Object.getOwnPropertyDescriptor() und Object.defineProperty().

Sowohl String- als auch Symbol-Eigenschaften werden kopiert.

Im Fehlerfall, zum Beispiel wenn eine Eigenschaft non-writable ist, wird ein TypeError ausgelöst, und das target-Objekt wird verändert, wenn Eigenschaften hinzugefügt wurden, bevor der Fehler ausgelöst wurde.

Parameter

Name Typ Default Beschreibung
$target Pflicht Object Das Zielobjekt — worauf die Eigenschaften der Quellen angewendet werden und das nach der Modifikation zurückgegeben wird. Wenn ein primitiver Wert als Ziel übergeben wird, wird er in ein Objekt umgewandelt.
$source1, …, sourceN Object Die Quellobjekt(e) — Objekte, welche die Eigenschaften enthalten, die angewendet werden sollen.

Rückgabewert

Typ
Object
Beschreibung
Das Zielobjekt.

Beispiele

Ein Objekt klonen

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

Warnung zum Deep Clone

const obj1 = { a: 0, b: { c: 0 } };
const obj2 = Object.assign({}, obj1);
console.log(obj2); // { a: 0, b: { c: 0 } }

obj1.a = 1;
console.log(obj1); // { a: 1, b: { c: 0 } }
console.log(obj2); // { a: 0, b: { c: 0 } }

obj2.a = 2;
console.log(obj1); // { a: 1, b: { c: 0 } }
console.log(obj2); // { a: 2, b: { c: 0 } }

obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 3 } }
console.log(obj2); // { a: 2, b: { c: 3 } }

// Deep Clone
const obj3 = { a: 0, b: { c: 0 } };
const obj4 = structuredClone(obj3);
obj3.a = 4;
obj3.b.c = 4;
console.log(obj4); // { a: 0, b: { c: 0 } }

Objekte zusammenführen

const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };

const obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed.

Objekte mit gleichen Eigenschaften zusammenführen

const o1 = { a: 1, b: 1, c: 1 };
const o2 = { b: 2, c: 2 };
const o3 = { c: 3 };

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

Symbol-typisierte Eigenschaften kopieren

const o1 = { a: 1 };
const o2 = { [Symbol("foo")]: 2 };

const obj = Object.assign({}, o1, o2);
console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox)
Object.getOwnPropertySymbols(obj); // [Symbol(foo)]

Eigenschaften in der prototype-Kette und nicht-enumerable Eigenschaften können nicht kopiert werden

const obj = Object.create(
  // foo is on obj's prototype chain.
  { foo: 1 },
  {
    bar: {
      value: 2, // bar is a non-enumerable property.
    },
    baz: {
      value: 3,
      enumerable: true, // baz is an own enumerable property.
    },
  },
);

const copy = Object.assign({}, obj);
console.log(copy); // { baz: 3 }

Primitives werden in Objekte verpackt

const v1 = "abc";
const v2 = true;
const v3 = 10;
const v4 = Symbol("foo");

const obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
// Primitives will be wrapped, null and undefined will be ignored.
// Note, only string wrappers can have own enumerable properties.
console.log(obj); // { "0": "a", "1": "b", "2": "c" }

// Primitives as the target are also wrapped to objects
const number = Object.assign(3, { a: 1 });
console.log(number); // Number {3, a: 1}
console.log(typeof number); // object
console.log(number.a); // 1

// null and undefined as targets throw TypeError
try {
  Object.assign(null, { a: 1 });
} catch (e) {
  console.log(e.message); // "Cannot convert undefined or null to object"
}

Exceptions unterbrechen den laufenden Kopiervorgang

const target = Object.defineProperty({}, "foo", {
  value: 1,
  writable: false,
}); // target.foo is a read-only property

Object.assign(target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 });
// TypeError: "foo" is read-only
// The Exception is thrown when assigning target.foo

console.log(target.bar); // 2, the first source was copied successfully.
console.log(target.foo2); // 3, the first property of the second source was copied successfully.
console.log(target.foo); // 1, exception is thrown here.
console.log(target.foo3); // undefined, assign method has finished, foo3 will not be copied.
console.log(target.baz); // undefined, the third source will not be copied either.

Accessors kopieren

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

let copy = Object.assign({}, obj);
console.log(copy);
// { foo: 1, bar: 2 }
// The value of copy.bar is obj.bar's getter's return value.

// This is an assign function that copies full descriptors
function completeAssign(target, ...sources) {
  sources.forEach((source) => {
    const descriptors = Object.keys(source).reduce((descriptors, key) => {
      descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
      return descriptors;
    }, {});

    // By default, Object.assign copies enumerable Symbols, too
    Object.getOwnPropertySymbols(source).forEach((sym) => {
      const 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 } }

// Wichtig · Fallstricke

Hinweis: Object.assign() wirft keinen Fehler bei null- oder undefined-Quellen.

Ein TypeError wird in einem der folgenden Fälle ausgelöst: der target-Parameter ist null oder undefined; die Zuweisung einer Eigenschaft am Zielobjekt schlägt fehl, zum Beispiel weil die Eigenschaft am Zielobjekt non-writable ist oder weil ihr setter einen Fehler wirft.