在不支持 可选链操作符(?.) 和 空值合并操作符(??) 的老版本浏览器内执行代码的时候,会中断并抛出语法错误。
已知如果 JS 里检测新内容是对象或者方法的时候,那么可以直接用布尔值判断,如
if (!window.Promise)
{
alert("浏览器不支持 Promise");
}
但 可选链操作符(?.) 和 空值合并操作符(??) 这种基础语法是没法像对象方法一样直接用布尔值判断的。比如像下面一样直接捕获错误,JS 语法解释器会在代码执行之前先抛出错误导致无法继续执行代码。
//以下代码并不会执行
try {
console.log(null ?? "支持空值合并操作符");
} catch (e) {
console.log("不支持空值合并操作符");
}
但是 JS 可以使用 eval 函数来执行字符串代码,发生语法错误的情况下会返回一个能够处理的语法错误。
try {
console.log(eval("null ?? \"支持空值合并操作符\""));
} catch (e) {
console.log("不支持空值合并操作符");
}
然后将代码整理扩充成一个完整的检测和提示流程
let needUpdateBrowser = (()=>{
try {
return !Boolean(eval("undefined?.undefined ?? true"));
} catch (e) {
if (e.name !== 'SyntaxError') throw e // Throw the error if it is not a SyntaxError
return true;
}
})();
if (needUpdateBrowser)
{
let browserVersion = ((UA)=>{
let regRes;
if (regRes = /\b(Firefox|Chrome)\/([\d\.]+)/ig.exec(UA))
{
return `${regRes[1]} ${regRes[2]}`;
}else if (regRes = /\bVersion\/([\d\.]+)\s+.*\b(Safari)\//ig.exec(UA))
{
return `${regRes[2]} ${regRes[1]}`;
}else
{
UA;
}
})(navigator.userAgent);
let alertStr;
if (/^zh-(?:han(?:s|t)-)?/.test(navigator.language)) {
alertStr =
`🙁浏览器内核版本太老
您的浏览器版本为:
${browserVersion}
您的浏览器不支持本程序使用的 可选链操作符(?.) 和 空值合并操作符(??)。
请更新您的浏览器到 Firefox(火狐) ≥ 74 或 Chrome(谷歌) ≥ 80 或 Safari(苹果) ≥ 13.1。`;
} else {
alertStr =
`🙁Browser kernel is too old
Your browser is:
${browserVersion}
Your browser does not support Optional chaining (?.) and Nullish coalescing operator (??) used in this program.
Please update your browser to Firefox ≥ 74 or Chrome ≥ 80 or Safari ≥ 13.1.`;
}
alert(alertStr);
document.write(alertStr.replace(/\n/g,'<br />'));
}
注意以上代码不能和有 可选链操作符(?.) 和 空值合并操作符(??) 的代码在同一个 js 文件里,不然仍然会被 JS 语法解释器优先抛出语法错误。
所以最好将这段代码独立放在一个 JS 文件里,并在 html 文件中最先引用,之后再引用其他代码。
另外以上整合代码用到了模板字符串,所以不支持 IE,需要支持 IE 的可以自己换成更老的语法。