This question already has answers here:
What do curly braces inside of function parameter lists do in es6?
(3 answers)
Closed 6 years ago.
(in javascript)
In this context:
const component = ({ name, value }) => <span></span>
Where the first argument of the arrow function is separated to its members. props => ({ name, value })
What is this called? I've seen some people doing this with babel but don't know what the proper term is.
Where the first argument of the arrow function is separated to its members. props => ({ name, value }) ... What is this called?
It's called parameter destructuring (sometimes argument destructuring, it's the destructuring part that's important). What you pass the function is an object, but what the function receives are properties from the object. That is, they've been taken out of the structure (the object) and made into distinct things (hence, "destructuring"):
const adams = ({question, answer}) => {
console.log(question);
console.log(answer);
};
adams({question: "Life, the Unverse, and Everything!", answer: 42});
JavaScript has destructuring in a few places, including function parameter lists as above. You can also do it with assignments:
const o = {question: "Life, the Unverse, and Everything!", answer: 42};
const {answer, question} = o;
console.log(question);
console.log(answer);
There's a related feature in ES2018 and later (but it's been supported in JSX code for years via tranpsiling): The ability to get the "rest" of the properties as an object:
// ES2018+
const adams = ({question, answer, ...rest}) => {
console.log(question);
console.log(answer);
console.log(rest);
};
adams({
question: "Life, the Unverse, and Everything!",
answer: 42,
legend: true,
missed: true
});
That ...rest inside the {} in the parameter list creates an object with the "rest" of the properties (those not captured as discrete arguments). It's the destructuring version of JavaScript's "rest params." You can do it in assignments, too:
// ES2018+
const o = {
question: "Life, the Unverse, and Everything!",
answer: 42,
legend: true,
missed: true
};
const {question, answer, ...rest} = o;
console.log(question);
console.log(answer);
console.log(rest);
The ES2015 spec had it for arrays, ES2018 added it for object properties.
It's called destructuring.
Here's an example on how it works and how to use it:
const employeeOne = { name: 'John', phone: '555-5555', age: 27 };
const { name, phone, age: john_age } = employeeOne;
console.log(name); // 'John'
console.log(phone); // '555-5555'
console.log(john_age); // '27'
sayHi = ({ name }) => console.log(`Hello ${name}, how are you?`);
sayHi(employeeOne); //'Hello John, how are you?'
Related
I'm reading an introduction to Redux reducers (https://redux.js.org/introduction/three-principles) which contains the following example of a reducer:
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
text: action.text,
completed: false
}
]
case 'COMPLETE_TODO':
return state.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: true
})
}
return todo
})
default:
return state
}
}
It seems from its documentation (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) that Object.assign() will 'merge together' all the objects passed into it. In this case, however, todo and {completed: true} are already objects, so I don't see the point of passing an empty object literal, {}, as the first argument to Object.assign(). Can anybody clarify this?
When you use Object.assign, the first object you give it will have all the rest of the objects merged into it. That is to say, the first object will be mutated.
If you want to avoid mutating the objects you're merging, it's helpful to pass in the empty object as the first parameter to prevent any of the component objects from changing.
Here's an example demonstrating the difference:
const obj1 = {
foo: "bar"
}
const obj2 = {
key: "value"
}
// Here, obj1 is the same after the Object.assign call
console.log(Object.assign({}, obj1, obj2));
console.log(obj1)
console.log(obj2)
console.log("\n\n")
// Note that after this call, obj1 holds both keys. So this will mutate it:
console.log(Object.assign(obj1, obj2));
console.log(obj1) // This is different now
console.log(obj2)
If you don't pass an empty object in, the original todo object will be modified. This may be what you want, but more often than not it isn't.
This is due to the way objects are all references, and are not cloned by default.
Short answer: Objects and Arrays are assignment by reference.
In this example, changing one will change the other, they are not immutable:
let x = {param:1}
const foo = (a) => {
a.param +=1;
console.log('response', x, a)
}
foo(x);
To fix that, we use Object.assign()
let x = {param:1}
const foo = (a) => {
let b = Object.assign({}, a);
b.param +=1;
console.log('response', b, x)
}
foo(x);
This question already has answers here:
Is it possible to destructure onto an existing object? (Javascript ES6)
(16 answers)
ES2015 deconstructing into an object [duplicate]
(1 answer)
How to get a subset of a javascript object's properties
(36 answers)
Closed 4 years ago.
I'm trying to understand ES6, specifically destructuring feature.
How can I translate these lines using destructuring?
const user = {...}
const sessionData = ({
session_id: user.session_id,
selector: user.selector,
validator: user.validator
})
I tried
const sessionData = {session_id, selector, validator} = user
But it raises a syntax error, because of course destructuring is for giving a certain variable a value from an object but I don't understand how to do something like this with an object
Use
const { session_id, selector, validator } = user;
Then
const sessionData = { session_id, selector, validator };
You could also do it like so (using anonymous functions)
const user = { session_id: 1, selector: "my-selector", validator: 1, unused: 3 };
const session = (({ session_id, selector, validator }) => ({ session_id, selector, validator }))(user);
console.log(session);
You can use a function to create the new object with the fields you want.
const original = { a: 1, b: 2, c: 3 };
const pick = (o, fields) => fields.reduce((acc, key) => {
acc[key] = o[key];
return acc;
}, {});
console.log(pick(original, ['a', 'b']));
Or use the comma operator to destructure and assign.
const original = { a: 1, b: 2, c: 3 };
const newone = ({ a, b } = original, { a, b });
console.log(newone);
But keep in mind that the comma operator creates global variables, if the variables to assign the destructure are not declared. Hope this helps.
I came across some syntax I haven't seen before. When I deal with objects and when using React, you can simplify namespacing by doing such as
let {someProp} = prevProps
Doing this allows me to avoid writing prevProps.someProp everytime I want to use it.
What I don't understand is this syntax
let {someProp: oldData} = prevProps
console.log(someProp) will show the value of the prevPros.someProp but WHERE does oldData come from???
console.log(olddata) above this line will show undefined but console.log(oldData) underneath will show the previous props.
let {someProp: myAlias} = prevProps
This syntax allows you use an alias, for example you can use myAlias in your code, instead someProp, it is called Object destructuring
As stated in the comments by #FelixKling here is the official reference.
Example from provided link:
let o = {p: 42, q: true};
let {p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
Yes:
let {someProp} = prevProps
is similar to this:
let someProp = prevProps.someProp;
And this:
let {someProp: oldData} = prevProps
would be similar to this:
let oldData = prevProps.someProp
Take a look at this link
Basically you are destructuring prevProps and in this case oldData will now be have the value of someProp
This syntax is one of the shiny new things in ES6 called object destructuring.
Here's an elaborate example on how you can use destructuring in different ways
const person = {
first: 'Jack',
last: 'Daniels',
address: {
city: 'Dallas',
}
};
// destructure as it is
const { first, last } = person;
// destructure with custom name
const { first: firstName, last: lastName } = person;
// destructure with default value
const { first, last, middle = 'The Boss' } = person;
// destructure with custom name and default value
const { first, last, middle: middleName = 'The Boss' } = person;
// destructure nested keys
const { first, last, address: { city } } = person;
// destructure nested keys with custom name
const { first, last, address: { city: myCity } } = person;
// destructure nested keys safely
const { first, last, address: { city } = {} } = person;
// destructure rest of the values
const { first, ...rest } = person; // => rest will have all keys but first
This question already has answers here:
One-liner to take some properties from object in ES 6
(12 answers)
Closed 4 years ago.
I'm constantly confused whether object destructuring in javascript applies in certain situations, and I've just come across one. In this code I am simply taking properties from the this object and assigning them to the same property/value on a new data object:
const data = {
rating: this.rating,
title: this.title,
text: this.text,
name: this.name,
location: this.location,
email: this.email,
files: this.files
};
Can some sort of object destructuring be used to accomplish this instead or is it unrelated to this use-case?
You can use the spread operator if you want all the own properties of this:
const data = {
...this
}
If you only need a selective few, you can delete the unnecessary properties afterwards, or set them to undefined (although that's different from non-existent/deleted properties):
const data = {
...this,
unwantedProp: undefined,
}
You could use something like this
const choose = (src, ...keys) => keys.reduce((result, key) => ({ ...result, [key]: src[key] }), {});
example usage
const choose = (src, ...keys) => keys.reduce((result, key) => ({ ...result, [key]: src[key] }), {});
const src = {
rating: 1,
title: 2,
text: 3,
name: 4,
location: 5,
email: 6,
files: 7,
not_me: 8
};
const data = choose(src, 'rating', 'title', 'text', 'name', 'location', 'email', 'files');
console.log(data);
In your case, you'd use this instead of src when calling choose
This question already has answers here:
Is it possible to destructure an object and generate a new object in a single statement? [duplicate]
(2 answers)
How to get a subset of a javascript object's properties
(36 answers)
One-liner to take some properties from object in ES 6
(12 answers)
Closed 5 years ago.
Is it possible to use destructuring assignment syntax to make it possible to extract data objects into another object instead distinct variables?
Example which produce distinct variables (foo, bar):
var {p: foo, q: bar} = {p: 42, q: true};
console.log(foo); // 42
console.log(bar); // true
I would need in stead to create a new object which contains the following properties as:
var n = {
foo: 42,
bar: true
}
It is not possible. The term destructuring implies that object is destructured to variables.
A way to not pollute the scope with temporary variables is to use IIFE for destructuring:
obj = (({ foo = 'foo', bar = 'bar' }) => ({ foo, bar }))(obj);
This will assign default values and will pick only valid keys from the object.
If picking is not necessary, the cleanest recipe to do this with native JS features is ES6 Object.assign:
obj = Object.assign({ foo: 'foo', bar: 'bar' }, obj);
Or ES2018 spread:
obj = { foo: 'foo', bar: 'bar', ...obj};
It sort of is, but you'll need two steps. You can't destructure directly from an object into another object, but you can make this elegant by using ES6 object notation and wrapping it into a function.
function transformObject(object) {
const { p: foo, q: bar } = object;
const newObject = {
foo,
bar
};
return newObject;
}
You cannot do it using destructuring, but you could use a helper function like this:
function retag(newStructure, source) {
var result = {};
for (var key in newStructure) {
result[key] = source[newStructure[key]];
}
return result;
}
console.log(retag(
{ foo: 'a', bar: 'b' },
{ a: false, b: 42, c: 'unused'}
));