Na przykład, jeśli mam dwa obiekty:
var foo = {
x: "bar",
y: "baz"
}
i
var oof = {}
i chciałem przenieść wartości xiy z foo do oof. Czy jest na to sposób za pomocą składni destrukturyzacji es6?
może coś takiego:
oof{x,y} = foo
javascript
ecmascript-6
destructuring
majorBummer
źródło
źródło
Object.assign(oof, foo)
Object.assign
Odpowiedzi:
Chociaż brzydkie i nieco powtarzalne, możesz to zrobić
({x: oof.x, y: oof.y} = foo);
który odczyta dwie wartości
foo
obiektu i zapisze je w odpowiednich lokalizacjach woof
obiekcie.Osobiście nadal wolałbym czytać
lub
['x', 'y'].forEach(prop => oof[prop] = foo[prop]);
chociaż.
źródło
var oof = {};
.({x: oof.x, y: oof.y} = foo)
? Myślę, że włożyłeś dodatkowe f in oof .Nie, destrukturyzacja nie obsługuje obecnie wyrażeń składowych w skrótach, ale tylko zwykłe nazwy właściwości. Były o tym rozmowy w ramach esdiscussingu, ale żadne propozycje nie trafią do ES6.
Możesz
Object.assign
jednak użyć - jeśli nie potrzebujesz wszystkich własnych właściwości, nadal możesz to zrobićvar foo = …, oof = {}; { let {x, y} = foo; Object.assign(oof, {x, y}) }
źródło
--harmony_destructuring
włączoną. Widzę „SyntaxError: Nieoczekiwany token”.{oof.x, oof.y} = foo
. A może naprawdę to przegapiłem.IMO to najłatwiejszy sposób na osiągnięcie tego, czego szukasz:
let { prop1, prop2, prop3 } = someObject; let data = { prop1, prop2, prop3 }; // data === { prop1: someObject.prop1, ... }
Zasadniczo, zniszczenie na zmienne, a następnie użyj skrótu inicjalizatora, aby utworzyć nowy obiekt. Nie ma potrzeby
Object.assign
W każdym razie myślę, że jest to najbardziej czytelny sposób. Możesz tutaj wybrać dokładnie te rekwizyty,
someObject
które chcesz. Jeśli masz istniejący obiekt, do którego chcesz po prostu scalić rekwizyty, zrób coś takiego:let { prop1, prop2, prop3 } = someObject; let data = Object.assign(otherObject, { prop1, prop2, prop3 }); // Makes a new copy, or... Object.assign(otherObject, { prop1, prop2, prop3 }); // Merges into otherObject
Innym, prawdopodobnie czystszym sposobem zapisania tego jest:
let { prop1, prop2, prop3 } = someObject; let newObject = { prop1, prop2, prop3 }; // Merges your selected props into otherObject Object.assign(otherObject, newObject);
Często używam tego do
POST
żądań, w których potrzebuję tylko kilku fragmentów dyskretnych danych. Ale zgadzam się, że powinien istnieć jeden liniowiec do tego.EDYCJA: PS - Niedawno dowiedziałem się, że w pierwszym kroku można użyć ultra destrukturyzacji, aby wyciągnąć zagnieżdżone wartości ze złożonych obiektów! Na przykład...
let { prop1, prop2: { somethingDeeper }, prop3: { nested1: { nested2 } } = someObject; let data = { prop1, somethingDeeper, nested2 };
Dodatkowo, podczas tworzenia nowego obiektu możesz użyć operatora rozszerzania zamiast Object. assign:
const { prop1, prop2, prop3 } = someObject; let finalObject = {...otherObject, prop1, prop2, prop3 };
Lub...
const { prop1, prop2, prop3 } = someObject; const intermediateObject = { prop1, prop2, prop3 }; const finalObject = {...otherObject, ...intermediateObject };
źródło
Poza tym
Object.assign
istnieje składnia rozprzestrzeniania obiektów, która jest propozycją etapu 2 dla ECMAScript.var foo = { x: "bar", y: "baz" } var oof = { z: "z" } oof = {...oof, ...foo } console.log(oof) /* result { "x": "bar", "y": "baz", "z": "z" } */
Ale aby skorzystać z tej funkcji, musisz użyć wtyczki
stage-2
lubtransform-object-rest-spread
wtyczki do babel. Oto demo na Babel zstage-2
źródło
Wtyczka BabelJS
Jeśli używasz BabelJS , możesz teraz aktywować moją wtyczkę
babel-plugin-transform-object-from-destructuring
( zobacz pakiet npm do instalacji i użytkowania ).Miałem ten sam problem opisany w tym wątku i było to dla mnie bardzo męczące, kiedy tworzyłeś obiekt z destrukturyzującej wyrażenia, szczególnie gdy musisz zmienić nazwę, dodać lub usunąć właściwość. Dzięki tej wtyczce utrzymanie takich scenariuszy stanie się znacznie łatwiejsze.
Przykład obiektu
let myObject = { test1: "stringTest1", test2: "stringTest2", test3: "stringTest3" }; let { test1, test3 } = myObject, myTest = { test1, test3 };
można zapisać jako:
let myTest = { test1, test3 } = myObject;
Przykład tablicy
let myArray = ["stringTest1", "stringTest2", "stringTest3"]; let [ test1, , test3 ] = myArray, myTest = [ test1, test3 ];
można zapisać jako:
let myTest = [ test1, , test3 ] = myArray;
źródło
let myTest = { test1, test3 } = myObject;
nie działaJest to całkowicie możliwe. Tylko nie w jednym oświadczeniu.
var foo = { x: "bar", y: "baz" }; var oof = {}; ({x: oof.x, y: oof.y} = foo); // {x: "bar", y: "baz"}
(Zwróć uwagę na nawiasy wokół zdania). Pamiętaj jednak, że czytelność jest ważniejsza niż gra w kodowanie :).
Źródło: http://exploringjs.com/es6/ch_destruising.html#sec_assignment-targets
źródło
Możesz po prostu użyć do tego restrukturyzacji:
const foo = {x:"a", y:"b"}; const {...oof} = foo; // {x:"a", y:"b"}
Lub scal oba obiekty, jeśli oof ma wartości:
const foo = {x:"a", y:"b"}; let oof = {z:"c"} oof = Object.assign({}, oof, foo)
źródło
oof = {...oof, ...foo}
Możesz zwrócić zniszczony obiekt w funkcji strzałkowej i użyć Object. assign (), aby przypisać go do zmiennej.
const foo = { x: "bar", y: "baz" } const oof = Object.assign({}, () => ({ x, y } = foo));
źródło
SUCHY
var a = {a1:1, a2: 2, a3: 3}; var b = {b1:1, b2: 2, b3: 3}; const newVar = (() => ({a1, a2, b1, b2})).bind({...a, ...b}); const val = newVar(); console.log({...val}); // print: Object { a1: 1, a2: 2, b1: 1, b2: 2 }
lub
console.log({...(() => ({a1, a2, b1, b2})).bind({...a, ...b})()});
źródło
Możesz zniszczyć obiekt przypisując go bezpośrednio do innego atrybutu obiektu.
Przykład pracy:
let user = {}; [user.name, user.username] = "Stack Overflow".split(' '); document.write(` 1st attr: ${user.name} <br /> 2nd attr: ${user.username}`);
Możesz pracować z niszczeniem używając zmiennych o tej samej nazwie atrybutu obiektu, który chcesz przechwycić, w ten sposób nie musisz tego robić:
let user = { name: 'Mike' } let { name: name } = user;
Użyj w ten sposób:
let user = { name: 'Mike' } let { name } = user;
W ten sam sposób można ustawić nowe wartości w strukturach obiektów, jeśli mają one tę samą nazwę atrybutu.
Spójrz na ten działający przykład:
// The object to be destructed let options = { title: "Menu", width: 100, height: 200 }; // Destructing let {width: w, height: h, title} = options; // Feedback document.write(title + "<br />"); // Menu document.write(w + "<br />"); // 100 document.write(h); // 200
źródło
Działa to w przeglądarce Chrome 53.0.2785.89
let foo = { x: "bar", y: "baz" }; let oof = {x, y} = foo; console.log(`oof: ${JSON.stringify(oof)}); //prints oof: { "x": "bar", "y": "baz" }
źródło
oof
po prostu otrzymuje odniesieniefoo
i omija całą destrukturyzację (przynajmniej w Chrome).oof === foo
alet oof = { x } = foo
jednak wraca{ x, y }
Wymyśliłem tę metodę:
exports.pick = function pick(src, props, dest={}) { return Object.keys(props).reduce((d,p) => { if(typeof props[p] === 'string') { d[props[p]] = src[p]; } else if(props[p]) { d[p] = src[p]; } return d; },dest); };
Którego możesz użyć w ten sposób:
let cbEvents = util.pick(this.props.events, {onFocus:1,onBlur:1,onCheck:'onChange'}); let wrapEvents = util.pick(this.props.events, {onMouseEnter:1,onMouseLeave:1});
tj. możesz wybrać właściwości, które chcesz uzyskać i umieścić je w nowym obiekcie. W przeciwieństwie do tego
_.pick
możesz również zmienić ich nazwę w tym samym czasie.Jeśli chcesz skopiować właściwości do istniejącego obiektu, po prostu ustaw
dest
argument.źródło
To trochę oszustwo, ale możesz zrobić coś takiego ...
const originalObject = { hello: 'nurse', meaningOfLife: 42, your: 'mom', }; const partialObject = (({ hello, your }) => { return { hello, your }; })(originalObject); console.log(partialObject); // { hello: 'nurse', your: 'mom' }
W praktyce myślę, że rzadko będziesz chciał tego używać. Poniższy tekst jest ZNACZNIE bardziej jasny ... ale nie tak zabawny.
const partialObject = { hello: originalObject.hello, your: originalObject.your, };
Kolejna zupełnie inna trasa, która obejmuje grzebanie w prototypie (teraz ostrożnie ...):
if (!Object.prototype.pluck) { Object.prototype.pluck = function(...props) { return props.reduce((destObj, prop) => { destObj[prop] = this[prop]; return destObj; }, {}); } } const originalObject = { hello: 'nurse', meaningOfLife: 42, your: 'mom', }; const partialObject2 = originalObject.pluck('hello', 'your'); console.log(partialObject2); // { hello: 'nurse', your: 'mom' }
źródło
To najbardziej czytelne i najkrótsze rozwiązanie, jakie mogłem wymyślić:
let props = { isValidDate: 'yes', badProp: 'no!', }; let { isValidDate } = props; let newProps = { isValidDate }; console.log(newProps);
To wyjdzie
{ isValidDate: 'yes' }
Byłoby miło, gdybyśmy kiedyś mogli coś takiego powiedzieć,
let newProps = ({ isValidDate } = props)
ale niestety nie jest to coś, co obsługuje ES6.źródło
To nie jest piękny sposób, ani go nie polecam, ale jest to możliwe, tylko dla wiedzy.
const myObject = { name: 'foo', surname: 'bar', year: 2018 }; const newObject = ['name', 'surname'].reduce( (prev, curr) => (prev[curr] = myObject[curr], prev), {}, ); console.log(JSON.stringify(newObject)); // {"name":"foo","surname":"bar"}
źródło
Aby to osiągnąć, możesz użyć metod klasy JSON w następujący sposób
const foo = { x: "bar", y: "baz" }; const oof = JSON.parse(JSON.stringify(foo, ['x','y'])); // output -> {x: "bar", y: "baz"}
Przekaż właściwości, które należy dodać do wynikowego obiektu jako drugi argument, aby
stringify
działać w formacie tablicy.Dokument MDN dla JSON.stringify
źródło