--- title: Object.assign() slug: Web/JavaScript/Reference/Global_Objects/Object/assign translation_of: Web/JavaScript/Reference/Global_Objects/Object/assign ---
{{JSRef}}

Sommario

La funzione Object.assign() copia tutte le proprietà enumerabili da uno o più oggetti di origine in un oggetto di destinazione. Restituisce l'oggetto di destinazione.

Sintassi

Object.assign(target, ...sources)

Parametri

target
L'oggetto di destinazione.
sources
Gli oggetti di origine.

Descrizione

La funzione Object.assign() copia soltanto le proprietà enumerabili appartenenti agli oggetti di origine (non quelle che fanno parte della loro catena dei prototipi) in un oggetto di destinazione. Utilizza [[Get]] sugli oggetti di origine e [[Put]] su quello di destinazione, quindi invoca getter e setter, quando presenti. Quindi assegna le proprietà, piuttosto che limitarsi a copiarle o a definirne di nuove. Ciò lo rende inadatto per aggiungere nuove proprietà in un prototipo se le proprietà vengono copiate da un oggetto contenente getter o setter. Per copiare le proprietà, incluso il fatto di essere enumerabili o no, in un prototipo, bisognerebbe usare {{jsxref("Object.defineProperty()")}}.

Vengono copiate sia le proprietà aventi come nomi delle {{jsxref("String", "stringhe")}} che dei {{jsxref("Symbol", "simboli")}}.

In caso di errore, per esempio se una proprietà non è sovrascrivibile, viene generato un {{jsxref("TypeError")}}, e l'oggetto di destinazione rimane invariato.

Notare che Object.assign() non genera un errore se uno dei valori di origine è {{jsxref("null")}} o {{jsxref("undefined")}}.

Esempi

Clonare un oggetto

Si potrebbe pensare di clonare un oggetto semplicemente assegnandolo ad un altra variabile:

var obj = { a: 1 };
var copia = obj;
console.log(obj, copia); // { a: 1 }, { a: 1 }
obj.a = 2;
console.log(obj, copia); // { a: 2 }, { a: 2 }
                         // Ma copia.a non valeva 1?

Utilizzando Object.assign() il problema non si verifica:

var obj = { a: 1 };
var copia = Object.assign({}, obj);
console.log(obj, copia); // { a: 1 }, { a: 1 }
obj.a = 2;
console.log(obj, copia); // { a: 2 }, { a: 1 }

Unire più oggetti

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

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, le proprietà vengono aggiunte all'oggetto di destinazione

Copiare proprietà aventi come indici dei simboli

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

var obj = Object.assign({}, o1, o2);
console.log(obj); // { a: 1, Symbol(foo): 2 }

Le proprietà ereditate o non-enumerabili non vengono copiate

var obj = Object.create({ foo: 1 }, { // foo è una proprietà ereditata
  bar: {
    value: 2  // bar è una proprietà non-enumerabile
  },
  baz: {
    value: 3,
    enumerable: true  // baz è una proprietà enumerabile
  }
});

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

I valori primitivi vengono trasformati in oggetti

var v1 = '123';
var v2 = true;
var v3 = 10;
var v4 = Symbol("foo");

var obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
// I valori primitivi vengono trasformati in oggetti, null e undefined ignorati.
// Notare che solo le stringhe hanno proprietà enumerabili
console.log(obj); // { "0": "1", "1": "2", "2": "3" }

Se viene generata un eccezione, la funzione si ferma

var destinazione = Object.defineProperty({}, 'foo', {
  value: 1,
  writeable: false
}); // destinazione.foo non può essere modificata

Object.assign(destinazione, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 });
// TypeError: "foo" is read-only
// L'eccezione viene generata quando si modifica destinazione.foo

console.log(destinazione.bar);  // 2, Il primo oggetto viene copiato correttamente
console.log(destinazione.foo2); // 3, La prima proprietà del secondo oggetto viene copiata correttamente
console.log(destinazione.foo);  // 1, L'eccezione viene generata qui
console.log(destinazione.foo3); // undefined, la funzione ha già finto di copiare
console.log(destinazione.baz);  // undefined, la funzione ha già finto di copiare

Copiare i getter

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

var copia = Object.assign({}, obj);
console.log(copia);
// { foo: 1, bar: 2 }, non viene copiato il getter obj.bar, ma il suo valore

// Questa funzione copia mantenendo getter e setter
function myAssign(target, ...sources) {
  sources.forEach(source => {
    Object.defineProperties(target, Object.keys(source).reduce((descriptors, key) => {
      descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
      return descriptors;
    }, {}));
  });
  return target;
}

var copia = myAssign({}, obj);
console.log(copia);
// { foo:1, get bar() { return 2 } }

Polyfill

Questo polyfill non supporta i simboli (che comunque non sono supportati da ECMAScript 5):

if (!Object.assign) {
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target, firstSource) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        var keysArray = Object.keys(Object(nextSource));
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

Specifiche

Specifica Stato Commenti
{{SpecName('ES2015', '#sec-object.assign', 'Object.assign')}} {{Spec2('ES2015')}} Definizione iniziale.

Compatibilità con i browser

{{CompatibilityTable}}
Funzionalità Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Supporto di base {{CompatChrome("45")}} {{CompatVersionUnknown}} {{CompatGeckoDesktop("34")}} {{CompatNo}} {{CompatOpera("32")}} {{CompatSafari("9")}}
Funzionalità Android Chrome for Android Edge Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Supporto di base {{CompatNo}} {{CompatChrome("45")}} {{CompatVersionUnknown}} {{CompatGeckoMobile("34")}} {{CompatNo}} {{CompatNo}} {{CompatVersionUnknown}}

Vedi anche