To conditionally add a property to an object, we can make use of the && operator. In the example above, in the first property definition on obj , the first expression ( trueCondition ) is true/truthy, so the second expression is returned, and then spread into the object.
When you want to add an element to the end of your array, use push(). If you need to add an element to the beginning of your array, try unshift(). And you can add arrays together using concat().
We can insert the elements wherever we want, which means we can insert either at starting position or at the middle or at last or anywhere in the array. After inserting the element in the array, the positions or index location is increased but it does not mean the size of the array is increasing.
When you spread into an array, you call the Symbol.iterator
method on the object. &&
evaluates to the first falsey value (or the last truthy value, if all are truthy), so
let arr2 = ['value2', ...(condition && arr)];
results in
let arr2 = ['value2', ...(false)];
But false
does not have a Symbol.iterator
method.
You could use the conditional operator instead, and spread an empty array if the condition is false:
let condition = false;
let arr1 = ['value1'];
let arr2 = ['value2', ...(condition ? arr1 : [])];
console.log(arr2);
(This works because the empty array does have the Symbol.iterator
method)
Object spread is completely different: it copies own enumerable properties from a provided object onto a new object. false
does not have any own enumerable properties, so nothing gets copied.
false
is not spreadable.
You need a spreadable object (the one where Symbol.iterator
is implemented) which returns nothing, if spreaded.
You could use an empty array as default value. This works even if arr
is falsy.
let condition = false;
let arr1 = ['value1'];
let arr2 = ['value2', ...(condition && arr || [])];
console.log(arr2);
This is a specification difference between the spread syntax for object literals and for array literals.
MDN briefly mentions it here -- I highlight:
Spread syntax (other than in the case of spread properties) can be applied only to iterable objects
The difference comes from the EcmaScript 2018 specification:
Concerning object spread syntax, see 12.2.6.8 Runtime Semantics: PropertyDefinitionEvaluation:
CopyDataProperties(object, fromValue, excludedNames)
where the fromValue is wrapped to an object with ToObject
, and therefore becomes iterable, even if fromValue is a primitive value like false
. Therefore {...false}
is valid EcmaScript.Concerning array spread syntax, see 12.2.5.2 Runtime Semantics: ArrayAccumulation:
GetValue(spreadRef)
which does not do the above mentioned wrapping. And so the subsequent call to GetIterator
will trigger an error on a primitive value, as it is not iterable. Therefore [...false]
is invalid EcmaScript.Example with objects:
const lessonMenuItems = [
...(true
? [
{
value: 'post',
},
]
: []),
{
value: 'assign',
},
]
Result:
lessonMenuItems = [
{
value: 'post',
},
{
value: 'assign',
},
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With