i was trying to solve this problem in javascript : Write a function that takes an object as argument containing properties with personal information .Extract firstName, lastName, size, and weight if available .If size or weight is given transform the value to a string .Attach the unit cm to the size .Attach the unit kg to the weight .Return a new object with all available properties that we are interested in .So i gave this solution :
function myFunction(obj) {
const {fn:fn , ln:ln ,size:s ,weight:w}= obj;
var newObj= {fn:fn , ln:ln};
if (s!==undefined && w!==undefined){
newObj={fn:fn , ln:ln ,size:s.toString()+'cm' ,weight:w.toString()+'kg'};
}
else if(s===undefined || w===undefined){
if (s===undefined && w!==undefined){
newObj={fn:fn , ln:ln ,weight:w.toString()+'kg'};
}
else if (s!==undefined && w===undefined) {
newObj={fn:fn , ln:ln ,size:s.toString()+'cm'};
}
}
return newObj
}
And the author's solution was :
function myFunction(obj) {
return {
fn: obj.fn,
ln: obj.ln,
...(obj.size && { size: `${obj.size}cm` }),
...(obj.weight && { weight: `${obj.weight}kg` }),
};
}
Can someone explain to me (or refer me to where i can find the answer) the lines with the spread operator and why does that work when the value of weight or size is undefined ? Thank you
i was trying to solve this problem in javascript : Write a function that takes an object as argument containing properties with personal information .Extract firstName, lastName, size, and weight if available .If size or weight is given transform the value to a string .Attach the unit cm to the size .Attach the unit kg to the weight .Return a new object with all available properties that we are interested in .So i gave this solution :
function myFunction(obj) {
const {fn:fn , ln:ln ,size:s ,weight:w}= obj;
var newObj= {fn:fn , ln:ln};
if (s!==undefined && w!==undefined){
newObj={fn:fn , ln:ln ,size:s.toString()+'cm' ,weight:w.toString()+'kg'};
}
else if(s===undefined || w===undefined){
if (s===undefined && w!==undefined){
newObj={fn:fn , ln:ln ,weight:w.toString()+'kg'};
}
else if (s!==undefined && w===undefined) {
newObj={fn:fn , ln:ln ,size:s.toString()+'cm'};
}
}
return newObj
}
And the author's solution was :
function myFunction(obj) {
return {
fn: obj.fn,
ln: obj.ln,
...(obj.size && { size: `${obj.size}cm` }),
...(obj.weight && { weight: `${obj.weight}kg` }),
};
}
Can someone explain to me (or refer me to where i can find the answer) the lines with the spread operator and why does that work when the value of weight or size is undefined ? Thank you
Share Improve this question edited Oct 23, 2024 at 14:20 VLAZ 29.2k9 gold badges63 silver badges84 bronze badges asked Jan 3, 2021 at 15:08 Youssef RafYoussef Raf 431 silver badge3 bronze badges 2- Javascript AND operator within assignment – VLAZ Commented Jan 3, 2021 at 15:10
-
2
Frankly, the author is probably trying to be too clever, with the consequence that if
size
orweight
is0
, it gets dropped (no equivalent property in the output). – T.J. Crowder Commented Jan 3, 2021 at 15:17
3 Answers
Reset to default 4There are a couple of things going on there:
Object spread syntax (it's not an operator) allows you to "spread" the values
null
andundefined
. When you do, no properties are added to the object being created. (This is just likeObject.assign
, which ignoresnull
andundefined
in its argument list.)The
&&
operator accepts two operands, evaluates the first, and if that value is falsy, takes that value as its result; it only evaluates the second operand and takes it as its result if the first value is truthy.
Taking those two things together, in the object literal, the ...(obj.size && { size: `${obj.size}cm` })
part works like this: if obj.size
is undefined
, it's basically ...undefined
which doesn't add any properties to the object. But if obj.size
is truthy, the second operand { size: `${obj.size}cm` }
(an object literal) is evaluated, results in an object, and you end up with ...{ size: `${obj.size}cm` }
which adds a size
property to the object being created.
Note: If obj.size
is 0
, there will be no size
property on the result, because 0
is falsy. So the author may well be incorrectly dropping size
or weight
with that solution:
function myFunction(obj) {
return {
fn: obj.fn,
ln: obj.ln,
...(obj.size && { size: `${obj.size}cm` }),
...(obj.weight && { weight: `${obj.weight}kg` }),
};
}
console.log(myFunction({fn: "fn", ln: "ln", size: 0}));
When obj.size
is 0
, you end up with ...0
in the object, which (in theory) creates a Number
object (rather than primitive) from the primitive 0
then spreads its properties. It doesn't put any properties in the object because, by default, Number
objects don't have any own, enumerable properties.
Now, if the problem is defined such that size
and weight
will never be 0
, fair enough. But I would think carefully before generalizing that solution.
The lines with the spread operator should work! But they will just add values if obj.size resp. obj.weight are not undefined!
In this case they add the keys size, resp. weight to the object.
If obj.size=10, then:
{key1:value1, key2:value2 ,..., keyN:valueN, ...(obj.size && { size: `${obj.size}cm` })}
=> {key1:value1, key2:value2 ,..., keyN:valueN, ...(10 && { size: `${10}cm` })}
=> {key1:value1, key2:value2 ,..., keyN:valueN, ...({ size: `10 cm` })
=> {key1:value1, key2:value2 ,..., keyN:valueN, size: `10 cm`}
If obj.size=undefined, then:
{key1:value1, key2:value2 ,..., keyN:valueN,...(obj.size && { size: `${obj.size}cm` })}
=> {key1:value1, key2:value2 ,..., keyN:valueN,...(undefined )}
=> {key1:value1, key2:value2 ,..., keyN:valueN}
Checkout my code
function myFunction(newobj) {
for (const key in newobj) {
if (key == 'size' || key == 'weight') {
key === 'size' ? newobj[key] += 'cm' : key === 'weight' ? newobj[key] += 'kg' : newobj
} else {
newobj
}
}
let { fn, ln, size, weight } = newobj;
let destobj = { fn, ln, size, weight }
if (size !== undefined || weight !== undefined) {
if (size !== undefined && weight === undefined) {
destobj = { fn, ln, size }
}
else if (weight !== undefined && size === undefined) {
destobj = { fn, ln, weight }
}
else {
destobj
}
}
else {
destobj = { fn, ln }
}
return destobj
}
console.log(myFunction({ fn: 'Martin', ln: 'Harper', age: 26, email: '[email protected]', weight: 102}))