# The Object assign() method

> Learn how JavaScript Object.assign() mutates a target with enumerable own string and Symbol properties, how conflicts are resolved, and why copies are shallow.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2019-03-28 | Updated: 2026-07-18 | Topics: [JavaScript](https://flaviocopes.com/tags/js/) | Canonical: https://flaviocopes.com/javascript-object-assign/

`Object.assign()` copies enumerable own properties from one or more source objects to a target object.

It mutates and returns the target:

```js
const car = {
  brand: 'Ford'
}

const result = Object.assign(car, {
  model: 'Fiesta'
})

car //{ brand: 'Ford', model: 'Fiesta' }
result === car //true
```

Both string and Symbol property keys are copied. Inherited and non-enumerable properties are not.

See the [MDN `Object.assign()` reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) and the [ECMAScript specification](https://tc39.es/ecma262/2026/multipage/fundamental-objects.html#sec-object.assign) for the complete rules.

## Merge objects

Use an empty target when you do not want to mutate any source:

```js
const details = {
  brand: 'Ford',
  model: 'Fiesta'
}

const status = {
  available: true
}

const car = Object.assign({}, details, status)
```

Later sources overwrite earlier properties with the same key:

```js
const car = Object.assign(
  {},
  { color: 'blue' },
  { color: 'red' }
)

car.color //'red'
```

## Copies are shallow

`Object.assign()` copies property values. When a value is an object, it copies the reference:

```js
const original = {
  model: 'Fiesta',
  details: {
    color: 'blue'
  }
}

const copied = Object.assign({}, original)

original.model = 'Focus'
original.details.color = 'yellow'

copied.model //'Fiesta'
copied.details.color //'yellow'
```

The top-level `model` values are independent. Both objects still reference the same nested `details` object.

Use `structuredClone()` when you need a deep copy and your values are supported by that algorithm.

## Getters and setters run

`Object.assign()` reads each source property and writes it to the target.

This means source getters and target setters run. Property descriptors are not copied:

```js
const source = {
  get total() {
    return 42
  }
}

const target = Object.assign({}, source)

Object.getOwnPropertyDescriptor(target, 'total')
//{ value: 42, writable: true, enumerable: true, configurable: true }
```

Use `Object.getOwnPropertyDescriptors()` with `Object.defineProperties()` when you need to preserve descriptors.

`null` and `undefined` sources are skipped. A `null` or `undefined` target throws a `TypeError`.
