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
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
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 w oof
obiekcie.
Osobiście nadal wolałbym czytać
oof.x = foo.x;
oof.y = foo.y;
lub
['x', 'y'].forEach(prop => oof[prop] = foo[prop]);
chociaż.
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})
}
--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 potrzebyObject.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 };
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
lub transform-object-rest-spread
wtyczki do babel. Oto demo na Babel zstage-2
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.
let myObject = {
test1: "stringTest1",
test2: "stringTest2",
test3: "stringTest3"
};
let { test1, test3 } = myObject,
myTest = { test1, test3 };
można zapisać jako:
let myTest = { test1, test3 } = myObject;
let myArray = ["stringTest1", "stringTest2", "stringTest3"];
let [ test1, , test3 ] = myArray,
myTest = [ test1, test3 ];
można zapisać jako:
let myTest = [ test1, , test3 ] = myArray;
let myTest = { test1, test3 } = myObject;
nie działa
Jest 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
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)
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));
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})()});
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
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"
}
oof
po prostu otrzymuje odniesienie foo
i omija całą destrukturyzację (przynajmniej w Chrome). oof === foo
a let 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.
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' }
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.
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"}
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.
Object.assign(oof, foo)