Este articulo necesita una revisión técnica. Cómo puedes ayudar.
Este articulo necesita una revisión editorial. Cómo puedes ayudar.
Traducción en curso
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.
Resumen
El método Object.assign()
es usado para copiar los valores de todas la propiedades propias enumerables de uno o más objetos fuente a un objeto destino. Regresará el objeto destino.
Sintaxis
Object.assign(objetivo, ...fuentes)
Parámetros
Objetivo
- El objeto destino.
Fuentes
- Los objetos origen.
Valor de retorno
El objeto destino es regresado.
Descripción
Las propiedades in el objetivo será sobreescrita por propiedades en los recursos si estos tienen la misma llave. Propiedades posteriores de los recursos podrán reescribir las anteriores.
El método Object.assign()
copia solo las propiedades enumerables y propias del objeto origen al objeto destino. Usa [[Get]]
en la origen y [[Set]]
en el destino, por lo que invocará los métodos de acceso y establecimiento (getters y setters). Por consiguiente asignará propiedades frente a solo copiar o definir propiedades nuevas. Esto puede hacer que sea inadecuado para fusionar propiedades nuevas en un prototipo si la fusión de fuentes contiene métodos de acceso (getters). Para copiar definiones de propiedades, incluyendo sus enumerabilidad, en prototipos, Object.getOwnPropertyDescriptor()
y Object.defineProperty()
debería ser usado en su lugar.
Ambos prototipos, String
y Symbol
, son copiados.
En caso de un error, por ejemplo si un prototipo es no tiene capacidad de escritura, un TypeError
será arrojado, y el objeto objetivo se mantendrá sin cambios.
Note que Object.assign()
no arroja una excepción sobre valores fuente null
o undefined
.
Ejemplos
Clonando un objeto
var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 }
Advertencia para clonado profundo
Para clonar profundamente, necesitamos usar otra alternativa. Esto debido a que Object.assign() copia la referencia de la propiedad cuando se asignada es un objeto.
function test() {
let a = { b: {c:4} , d: { e: {f:1}} }
let g = Object.assign({},a)
let h = JSON.parse(JSON.stringify(a));
console.log(g.d) // { e: { f: 1 } }
g.d.e = 32
console.log('g.d.e set to 32.') // g.d.e set to 32.
console.log(g) // { b: { c: 4 }, d: { e: 32 } }
console.log(a) // { b: { c: 4 }, d: { e: 32 } }
console.log(h) // { b: { c: 4 }, d: { e: { f: 1 } } }
h.d.e = 54
console.log('h.d.e set to 54.') // h.d.e set to 54.
console.log(g) // { b: { c: 4 }, d: { e: 32 } }
console.log(a) // { b: { c: 4 }, d: { e: 32 } }
console.log(h) // { b: { c: 4 }, d: { e: 54 } }
}
test();
Fusionando objetos
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 }, objeto objetivo es cambiado en sí mismo.
Fusionando objetos con propiedades similares
var o1 = { a: 1, b: 1, c: 1 };
var o2 = { b: 2, c: 2 };
var o3 = { c: 3 };
var obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3
Las propiedades son sobreescritas por otros objetos que tienen las mismas propiedades en otros parámetros
Copiando propiedades de tipo símbolo
var o1 = { a: 1 };
var o2 = { [Symbol('foo')]: 2 };
var obj = Object.assign({}, o1, o2);
console.log(obj); // { a: 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox)
Object.getOwnPropertySymbols(obj); // [Symbol(foo)]
Propiedades heredadas y propiedades no enumerables no pueden ser copiadas
var obj = Object.create({ foo: 1 }, { // foo es una propiedad heredada. bar: { value: 2 // bar es una propiedad no enumberable. }, baz: { value: 3, enumerable: true // baz es una propiedad propia enumerable. } }); var copy = Object.assign({}, obj); console.log(copy); // { baz: 3 }
Primitivos serán envueltos en objetos
var v1 = '123'; var v2 = true; var v3 = 10; var v4 = Symbol('foo') var 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": "1", "1": "2", "2": "3" }
Excepciones interrumpirán la tarea de copiado andante
var target = Object.defineProperty({}, 'foo', { value: 1, writeable: 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.
Copiando métodos de acceso.
var obj = { foo: 1, get bar() { return 2; } }; var 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 a assign function can copy accessors. 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 copy = myAssign({}, obj); console.log(copy); // { foo:1, get bar() { return 2 } }
Polyfill
Este polyfill no soporta propiedades simbolo, en ES5 no se tienen simbolos de cualquier forma.
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; } 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; } }); }
Especificaciones
Especificación | Estado | Comentario |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Object.assign' in that specification. |
Standard | Definición inicial |
Compatibilidad de navegadores
Caracteristica | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Soporte básico | 45 | 34 (34) | No support | No support | No support |
Caracteristica | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Soporte básico | No support | No support | 34.0 (34) | No support | No support | No support |