如何判断 JavaScript 运算符是否受支持?

3

刚刚意识到我的脚本在我的 iPhone 上无法运行,发现以下这一行是罪魁祸首。

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

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator 显示Safari 13.4支持空值合并运算符,但我认为我的版本是13.3。不管怎样,需要解决。

有没有一种办法可以通过在客户端执行JavaScript来判断是否支持诸如??的运算符? 如果是这样,如果必要,我会检测并执行一些备选方案。

略微偏离主题,但是否有人知道适用于Safari和iOS的polyfill?


1
你可以将它放在try catch块中。 - Roberto Zvjerković
2
@ritaj 是正确的,但如果你这样做,你需要写两次代码 - 一次支持环境,一次不支持环境。你可以跳过这个步骤,使用Babel转译代码。 - VLAZ
或者你可以使用最新的JavaScript规范并编译为较旧的版本,以支持您想要支持的浏览器。 - crashmstr
3个回答

3
你可以尝试这个检查。
const operatorSupported = eval('null??true')

但是,如果不支持“??”,eval将会抛出异常,因此函数应该使用try...catch语句。

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

为了运行它一次,该代码块被包装在匿名函数中,这样eval的性能会稍微提高一些。

嘿,不熟悉Lamdatest。这段代码对于支持它的浏览器返回true,对于不支持它的浏览器返回undefined。可能会有关于eval的安全检查,但如果您托管网站,应该没问题。 - uke
你可能是对的,我试图确认但无法确定。我回到了Lamdatest尝试eval('null?true:false'),但显然有六分钟的试用时间限制,我不小心使用了它。 - user1032531
谢谢,看起来可以用,但我可能会选择imvain2的解决方案,除非我能找到一个好的实现方式。我在考虑像这样的东西:nullishCoalese('this.currentElements[0].labels[0].textContent', 'This field'); 这将两者都传递给您的解决方案,尝试进行评估,如果无法执行,则执行一些不太高效的解决方案。 - user1032531

3

不必检查函数是否有效,只需重写它以确保最终结果相同。

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

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

你甚至可以有一个可重用的函数来完成相同的事情:

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

谢谢imvain2,虽然我很感激你的回答并可能会使用它,但它并没有真正回答我的具体问题。无论如何,我会给你点赞。 - user1032531

2

如何检测运营商支持?

仅使用try/catch是不可能的。您可以尝试捕获表达式,但不能使用新语法。例如,此代码甚至无法解析:

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

support_dollar_operator(); // your browser exploded before that

然而,使用 eval 是可能的:
const support_dollar_operator = () => {
  try {
    eval(`1 $ 2`);
    return true;
  } catch (e) {
    return false;
  }
}

support_dollar_operator();
//=> false

是否可以用polyfill方式实现一个运算符?

是的,也不是。

是的,你可以使用像Babel这样的工具来使用新的运算符,但在幕后,如果该运算符不受您的目标受众支持,它将重写您的代码。它看起来会像这样:

// your code
bar ?? 'baz'

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

如何解决您的问题?

由于您没有发布错误信息,因此我们无法假设您的问题是由于不支持??引起的。

即使支持??,这也会失败:

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

??运算符并不适用于提供当路径上某些内容未定义时的回退。这是?.“可选链” 运算符的工作:“可选链”(optional chaining)

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

如果 AB 未定义,您的代码可能会导致错误:

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

好消息是,在iOS上的Safari浏览器中支持?.运算符。

谢谢您的回复。也许可以扩展使用??,如果抛出异常,则按.(并处理数组)拆分并递归检查每个属性。 - user1032531
@user1032531 看更新。我认为我们需要先看到错误信息。 - customcommander
谢谢customercommander。是的,我也想看到错误信息!在Chrome、IE、FF等浏览器上没有问题,但在我的iPhone7上有问题。然而,在手机上似乎没有查看错误的方法。我的hack解决方案是在各个地方放置警报消息,以便我可以排除潜在的罪犯。我还包括了一些只有几行脚本的页面,似乎??是问题所在。如果您有更好的查看错误的方法,请告知!关于?.更合适的问题,它们看起来很接近,但我认为您是正确的。PHP只有??,这就是我使用它的原因。 - user1032531

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接