web-dev-qa-db-fra.com

Est-il possible de se déstructurer sur un objet existant? (Javascript ES6)

Par exemple si j'ai deux objets: 

var foo = {
  x: "bar",
  y: "baz"
}

et 

var oof = {}

et je voulais transférer les valeurs x et y de foo à oof. Y a-t-il un moyen de faire cela en utilisant la syntaxe de déstructuration es6?

peut-être quelque chose comme: 

oof{x,y} = foo
88
majorBummer

Bien que moche et un peu répétitif, vous pouvez faire

({x: oof.x, y: oof.y} = foo);

qui lira les deux valeurs de l'objet foo et les écrira à leurs emplacements respectifs sur l'objet oof.

Personnellement je préfère quand même lire

oof.x = foo.x;
oof.y = foo.y;

ou

['x', 'y'].forEach(prop => oof[prop] = foo[prop]);

bien que.

57
loganfsmyth

Non, la déstructuration ne prend pas en charge les expressions de membre en abrégé, mais uniquement les noms de propriétés en clair à l'heure actuelle. Il y a eu { eu des pourparlers } à ce sujet sur esdiscuss, mais aucune proposition ne sera intégrée à ES6.

Cependant, vous pouvez peut-être utiliser Object.assign - si vous n'avez pas besoin de toutes vos propres propriétés, vous pouvez toujours le faire.

var foo = …,
    oof = {};
{
    let {x, y} = foo;
    Object.assign(oof, {x, y})
}
30
Bergi

IMO c'est la manière la plus simple d'accomplir ce que vous cherchez:

let { prop1, prop2, prop3 } = someObject;
let data = { prop1, prop2, prop3 };

  // data === { prop1: someObject.prop1, ... }

Fondamentalement, déstructurez en variables puis utilisez le raccourci de l’initialiseur pour créer un nouvel objet. Pas besoin de Object.assign

Je pense que c'est le moyen le plus lisible, de toute façon. Vous pouvez par la présente sélectionner les accessoires exacts que vous voulez parmi someObject. Si vous avez un objet existant sur lequel vous souhaitez simplement fusionner les accessoires, procédez comme suit:

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

Une autre façon de l'écrire, sans doute plus propre, est la suivante:

let { prop1, prop2, prop3 } = someObject;
let newObject = { prop1, prop2, prop3 };

// Merges your selected props into otherObject
Object.assign(otherObject, newObject);

J'utilise ceci pour les demandes POST où je n'ai besoin que de quelques données discrètes. Mais, je suis d’accord, il devrait y avoir un one-line pour faire cela.

15
Zfalen

Outre Object.assign, il existe la syntaxe object spread qui est une proposition de stade 2 pour ECMAScript.

var foo = {
  x: "bar",
  y: "baz"
}

var oof = { z: "z" }

oof =  {...oof, ...foo }

console.log(oof)

/* result 
{
  "x": "bar",
  "y": "baz",
  "z": "z"
}
*/

Mais pour utiliser cette fonctionnalité, vous devez utiliser le plugin stage-2 ou transform-object-rest-spread pour babel. Voici une démo sur babel avec stage-2

8
Gaafar

Plugin BabelJS

Si vous utilisez BabelJS, vous pouvez maintenant activer mon plugin babel-plugin-transform-object-from-destructuring ( voir le paquet npm pour l'installation et l'utilisation ).

J'avais le même problème décrit dans ce fil de discussion et pour moi, c'était très épuisant de créer un objet à partir d'une expression de déstructuration, en particulier lorsque vous devez renommer, ajouter ou supprimer une propriété. Avec ce plugin, la maintenance de tels scénarios devient beaucoup plus facile pour vous.

Exemple d'objet

let myObject = {
  test1: "stringTest1",
  test2: "stringTest2",
  test3: "stringTest3"
};
let { test1, test3 } = myObject,
  myTest = { test1, test3 };

peut être écrit comme:

let myTest = { test1, test3 } = myObject;

Exemple de tableau

let myArray = ["stringTest1", "stringTest2", "stringTest3"];
let [ test1, , test3 ] = myArray,
  myTest = [ test1, test3 ];

peut être écrit comme:

let myTest = [ test1, , test3 ] = myArray;
5
Matthias Günter

C'est totalement possible. Juste pas dans une déclaration.

var foo = {
    x: "bar",
    y: "baz"
};
var oof = {};
({x: oof.x, y: oof.y} = foo); // {x: "bar", y: "baz"}

(Notez les parenthèses autour de la déclaration.) .__ Mais gardez à l'esprit que la lisibilité est plus importante que le code-golf :).

Source: http://exploringjs.com/es6/ch_destructuring.html#sec_assignment-targets

3
Hampus Ahlgren

DRY

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 }

ou

console.log({...(() => ({a1, a2, b1, b2})).bind({...a, ...b})()});
1
user5733033

Vous pouvez retourner l'objet déstructuré dans une fonction de flèche et utiliser Object.assign () pour l'assigner à une variable.

const foo = {
  x: "bar",
  y: "baz"
}

const oof = Object.assign({}, () => ({ x, y } = foo));
1
Ben Copeland

Vous pouvez simplement utiliser la restructuration pour cela comme ceci:

const foo = {x:"a", y:"b"};
const {...oof} = foo; // {x:"a", y:"b"} 

Ou fusionnez les deux objets si oof a des valeurs:

const foo = {x:"a", y:"b"};
let oof = {z:"c"}
oof = Object.assign({}, oof, foo)
1
CampSafari

Vous pouvez détruire un objet assigné directement à un autre attribut d'objet.

Exemple de travail:

let user = {};
[user.name, user.username] = "Stack Overflow".split(' ');
document.write(`
1st attr: ${user.name} <br /> 
2nd attr: ${user.username}`);

Vous pouvez travailler avec la destruction en utilisant des variables avec le même nom d'attribut d'objet que vous voulez capturer, de cette façon, vous n'avez pas besoin de le faire:

let user = { name: 'Mike' }
let { name: name } = user;

Utilisez cette manière:

let user = { name: 'Mike' }
let { name } = user;

De la même manière, vous pouvez définir de nouvelles valeurs pour les structures d'objet si elles portent le même nom d'attribut.

Regardez cet exemple de travail:

// 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
0
RPichioli

C'est une sorte de triche, mais vous pouvez faire quelque chose comme ça ...

const originalObject = {
  hello: 'nurse',
  meaningOfLife: 42,
  your: 'mom',
};

const partialObject = (({ hello, your }) => {
  return { hello, your };
})(originalObject);

console.log(partialObject); // ​​​​​{ hello: 'nurse', your: 'mom' }​​​​​

En pratique, je pense que vous voudrez rarement utiliser cela. Ce qui suit est BEAUCOUP plus clair ... mais pas aussi amusant.

const partialObject = {
  hello: originalObject.hello,
  your: originalObject.your,
};

Une autre route complètement différente, qui inclut le nettoyage du prototype (attention maintenant ...):

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' }
0
Bart

Ce n'est pas une belle façon, je ne le recommande pas non plus, mais c'est possible comme ça, juste pour le savoir.

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"}
0
Sornii

Je suis venu avec cette méthode:

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);
};

Que vous pouvez utiliser comme ceci:

let cbEvents = util.pick(this.props.events, {onFocus:1,onBlur:1,onCheck:'onChange'});
let wrapEvents = util.pick(this.props.events, {onMouseEnter:1,onMouseLeave:1});

c’est-à-dire que vous pouvez choisir les propriétés que vous voulez et les placer dans un nouvel objet Contrairement à _.pick , vous pouvez également les renommer en même temps.

Si vous souhaitez copier les accessoires sur un objet existant, définissez simplement le paramètre dest arg.

0
mpen

Cela fonctionne en 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"
}
0
user1577390

C'est la solution la plus lisible et la plus courte que je pourrais trouver:

let props = { 
  isValidDate: 'yes',
  badProp: 'no!',
};

let { isValidDate } = props;
let newProps = { isValidDate };

console.log(newProps);

Il va sortir { isValidDate: 'yes' }

Il serait bien qu’un jour on puisse dire quelque chose comme let newProps = ({ isValidDate } = props) mais malheureusement ce n’est pas quelque chose que ES6 supporte.

0