Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does JavaScript's spread syntax allow {...null} but not [...null]? [duplicate]

Was updating a bit of code today that returns optional props to a React component. I discovered that even though the function sometimes returns null, it wouldn't error when the return value was immediately unpacked.

Pedantic summary of the code:

const returnPropsOrDont = (condition) => {
  if (condition) return null;
  return { optionalProp: 'foo' };
}
...
render() {
  const { condition } = props;
  return <SomeComponent
           staticProp="staticProp"
           {...returnPropsOrDont(condition)}
         />
}

Upon realizing this was cool, I ran to the console and tried it out on Objects and Arrays. Alas -

   > {...null} // {}
   > {...undefined} // {}, which is interesting because null is an object but undefined is not
   > [...null] // Uncaught TypeError: object null is not iterable

I did some light Googling and found one article which suggests that TypeScript considers it a feature to make sure optionally defined values don't haunt an unsuspecting developer. Fine, but a) I'm not using TypeScript, and b) I have no idea why JS wouldn't guard Arrays in the same way.

Since this does seem like a guard against optionally defined values, why is {...null} fine and [...null] not?

like image 418
Stick Avatar asked Jul 13 '20 22:07

Stick


2 Answers

Normally, uses of ...x requires x to be iterable because the point of ... is normally to flatten an iterable into its components. An array is a prime example of an iterable.

null is not iterable. It has no components, so it doesn't make sense to iterate over null. for (const e of null) will similarly fail, since of also requires an iterable.

However, {...x} requires x to be enumerable because it needs not just values, but keys along with them. An object is a prime example of an enumerable.

null is enumerable. null is sometime treated as an object, and this is one of those cases. Objects are enumerable because they can have properties. for (const p in null) will similarly succeed, since in requires an enumerable.

like image 90
ikegami Avatar answered Sep 23 '22 04:09

ikegami


[…null] - here you use spear operator and it works only for iterable objects (like strings, arrays, generators or custom iterable objects), but null isn't iterable object and will recieved error. You can create your own iterable object be adding special property Symbol. iterator

{...null} - works because typeof null == 'object', but in real life it doesn't make sense

like image 37
Slawa Eremin Avatar answered Sep 25 '22 04:09

Slawa Eremin