How to tell if a JavaScript operator is supported?

Viewed 89

Just realized my script doesn't work on my iphone, and found that the following line is the culprit.

return (this.currentElements[0].labels[0].textContent ?? 'This field') + " must be one of " + validValues.join(', ');

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator indicates that Safari 13.4 supports it, and I think I have 13.3. Regardless, need to resolve.

Is there a way to tell if an operator such as ?? is supported by executing JavaScript on the client? If so, I would detect and execute some alternate approach if necessary.

A little off topic, but does anyone know of a polyfill that will work with Safari and iOS?

3 Answers

You can try this check

const operatorSupported = eval('null??true')

but the eval will throw if ?? is not supported so function should be try...catch

const operatorSupported = (() => {
  try {
    return eval('null??true');
  } catch(err){
    return false 
  }
})();

In order to run it once, the block is wrapped into anonymous function so eval becomes a bit performant

Instead of checking to see if the function works, you can just rewrite it so that the end result will be the same.

_content = this.currentElements[0].labels[0].textContent;

return ((_content === null || _content === undefined) ? 'This field' : _content) + " must be one of " + validValues.join(', ');

You can even have a reusable function that does the same thing:

function nullish(a,b){
  return (a === null || a === undefined) ? b : a
}

How to detect operator support?

Using try/catch alone is impossible. You can try/catch expressions but not new syntax. For example this code wouldn't even parse:

const support_dollar_operator = () => {
  try {
    1 $ 2;
    return true;
  } catch (e) {
    return false;
  }
}

support_dollar_operator(); // your browser exploded before that

However it is possible with eval:

const support_dollar_operator = () => {
  try {
    eval(`1 $ 2`);
    return true;
  } catch (e) {
    return false;
  }
}

support_dollar_operator();
//=> false

Is it possible to polyfill an operator?

Yes and no.

Yes you can use a new operator with tools such as Babel but behind the scene it will rewrite your code if that operator isn't supported by your target audience. It would look like this:

// your code
bar ?? 'baz'

// transpiled
bar == undefined ? 'baz' : bar

How do you fix your issue?

You haven't posted an error message so we can't assume that your issue is caused by ?? not being supported.

This would fail even if ?? is supported:

var foo;
foo.bar ?? 'baz';
//=> ERR: Uncaught TypeError: Cannot read property 'bar' of undefined

The ?? operator isn't meant to provide a fallback if something along the path is undefined. This is the job of the ?. "optional chaining" operator:

var foo;
foo?.bar ?? 'baz';
//=> 'baz'

In your code an error could be caused if either A or B is undefined:

(this.currentElements[0].labels[0].textContent ?? 'This field')
//    ^                  ^
//    A                  B

The good news is that the ?. operator is supported in Safari on iOS

Related