This is a new technology, part of the ECMAScript 2015 (ES6) standard.
This technology's specification has been finalized, but check the compatibility table for usage and implementation status in various browsers.
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 Object.defineProperty()
.
Vengono copiate sia le proprietà aventi come nomi delle stringhe
che dei simboli
.
In caso di errore, per esempio se una proprietà non è sovrascrivibile, viene generato un TypeError
, e l'oggetto di destinazione rimane invariato.
Notare che Object.assign()
non genera un errore se uno dei valori di origine è null
o 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()
non succede più questo problema:
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 |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Object.assign' in that specification. |
Standard | Definizione iniziale. |
Compatibilità con i browser
Funzionalità | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Supporto di base | No support | 34 (34) | No support | No support | No support |
Funzionalità | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Supporto di base | No support | No support | 34.0 (34) | No support | No support | No support |