😰 Optional chaining trap !

#javascript#babel

A few days ago, an announcement that many expected was published in TC39 Stage 3. Optional Chaining

Example here with

It is a great news for Javascript ! This feature is awesome but…

Please agree with me, this feature will not be available tomorrow in our browsers. In stage 3, it is very likely that this feature will be added in the next release of ES.

But

We will need to babel it for a very long time.

If you take a look at @babel/plugin-proposal-optional-chaining, this is how babel will transpile it.

babel transpile example

This is kind of a very verbose output.

Let’s imagine that we use this feature very many times in a web application, and you use it for deep case.

const foo = everything?.could?.be.nullable?.maybe

// Babel will generate this output

var _everything, _everything$could, _everything$could$be$

var foo =
  (_everything = everything) === null || _everything === void 0
    ? void 0
    : (_everything$could = _everything.could) === null ||
      _everything$could === void 0
    ? void 0
    : (_everything$could$be$ = _everything$could.be.nullable) === null ||
      _everything$could$be$ === void 0
    ? void 0
    : _everything$could$be$.maybe

// Terser would modify like this
l, n, o
null === (l = everything) ||
  void 0 === l ||
  null === (n = l.could) ||
  void 0 === n ||
  null === (o = n.be.nullable) ||
  void 0 === o ||
  o.maybe

It’s going to be really verbose in your bundles. The transformation made by babel in the state does not at all share the nullsafe access mechanism as lodash.get can do. Even if lodash is very/too heavy. It offers a more efficient nullsafe implementation while generating less code.

You’re going to tell me,

“What the heck! Antoine, it’s not the first time we’ve used a not-so-great polyfill to be able to use a new feature of EcmaScript”

Yeah

Ok but this time we can still look a few minutes to propose an implementation of a less trivial polyfill. This solution cannot really be applied in a world where the web developer turns into a Ko hunter.

Let’s look at how lodash.get works. Github link

import castPath from './castPath.js'
import toKey from './toKey.js'

/**
 * The base implementation of `get` without support for default values.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array|string} path The path of the property to get.
 * @returns {*} Returns the resolved value.
 */
function baseGet(object, path) {
  path = castPath(path, object)

  let index = 0
  const length = path.length

  while (object != null && index < length) {
    object = object[toKey(path[index++])]
  }
  return index && index == length ? object : undefined
}

export default baseGet

It’s very effective (very compact). What if the polyfill of the Optional Chaining involved the application of a utility function like lodash.get?

What’s your opinion on that?

Feel free to share and react if you liked this article.

\n

It is a great news for Javascript ! This feature is awesome but…

\n

Please agree with me, this feature will not be available tomorrow in our browsers. In stage 3, it is very likely that this feature will be added in the next release of ES.

\n

But

\n

We will need to babel it for a very long time.

\n

If you take a look at @babel/plugin-proposal-optional-chaining, this is how babel will transpile it.

\n

\n \n \n \n \n \n \n

\n

This is kind of a very verbose output.

\n

Let’s imagine that we use this feature very many times in a web application, and you use it for deep case.

\n
const foo = everything?.could?.be.nullable?.maybe\n\n// Babel will generate this output\n\nvar _everything, _everything$could, _everything$could$be$\n\nvar foo =\n  (_everything = everything) === null || _everything === void 0\n    ? void 0\n    : (_everything$could = _everything.could) === null ||\n      _everything$could === void 0\n    ? void 0\n    : (_everything$could$be$ = _everything$could.be.nullable) === null ||\n      _everything$could$be$ === void 0\n    ? void 0\n    : _everything$could$be$.maybe\n\n// Terser would modify like this\nl, n, o\nnull === (l = everything) ||\n  void 0 === l ||\n  null === (n = l.could) ||\n  void 0 === n ||\n  null === (o = n.be.nullable) ||\n  void 0 === o ||\n  o.maybe
\n

It’s going to be really verbose in your bundles. The transformation made by babel in the state does not at all share the nullsafe access mechanism as lodash.get can do. Even if lodash is very/too heavy. It offers a more efficient nullsafe implementation while generating less code.

\n

You’re going to tell me,

\n
\n

“What the heck! Antoine, it’s not the first time we’ve used a not-so-great polyfill to be able to use a new feature of EcmaScript”

\n
\n

Yeah

\n

Ok but this time we can still look a few minutes to propose an implementation of a less trivial polyfill. This solution cannot really be applied in a world where the web developer turns into a Ko hunter.

\n

Let’s look at how lodash.get works. Github link

\n
import castPath from './castPath.js'\nimport toKey from './toKey.js'\n\n/**\n * The base implementation of `get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n  path = castPath(path, object)\n\n  let index = 0\n  const length = path.length\n\n  while (object != null && index < length) {\n    object = object[toKey(path[index++])]\n  }\n  return index && index == length ? object : undefined\n}\n\nexport default baseGet
\n

It’s very effective (very compact). What if the polyfill of the Optional Chaining involved the application of a utility function like lodash.get?

\n

What’s your opinion on that?

\n

Feel free to share and react if you liked this article.

","image":["https://blog.slashgear.dev/static/16d8a38331d1434b3f319733b7a828fa/6edcc/cat.jpg","https://blog.slashgear.dev/static/16d8a38331d1434b3f319733b7a828fa/e14ae/cat.jpg","https://blog.slashgear.dev/static/16d8a38331d1434b3f319733b7a828fa/db124/cat.jpg"],"keywords":["javascript","babel"],"author":{"@type":"Person","name":"Antoine Caron"},"publisher":{"@type":"Organization","name":"Antoine Caron","logo":{"@type":"ImageObject","url":"https://blog.slashgear.dev/static/picture_of_me-cb64a6913d2e31dbb5dab1f4d113d077.jpg"}}}

Written by Antoine Caron who lives and works in Lyon (France) building useful things at Bedrock. You should follow him on Twitter. Take a look at my friends websites. You could also take a look at the conferences I gave. If you want to see my professional background, my resume is available here.

If you like some content of this blog, or it has helped you, please consider donating to the Abbé Pierre Foundation which I personally support.
"We are only ever happy in the happiness we give. To give is to receive."