检测浏览器是否支持可选链操作符(?.) 和 空值合并操作符(??)

本文探讨了如何在不支持新语法的浏览器中处理可选链(?.)和空值合并(??)操作,通过eval函数绕过语法错误,提供了一个完整的检测与提示代码示例。

在不支持 可选链操作符(?.) 和 空值合并操作符(??) 的老版本浏览器内执行代码的时候,会中断并抛出语法错误。

 已知如果 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 的可以自己换成更老的语法。

JavaScript 中,可选链操作符(`?.`)是一种语法糖,用于安全地访问对象的深层属性或调用方法,而无需显式检查每一层是否为 `null` 或 `undefined`。如果某个引用为空,则表达式会短路并返回 `undefined`,而是抛出错误。 ### 可选链操作符的基本使用 可选链支持以下几种形式: - `object?.property`:访问对象的属性。 - `object?.[expression]`:通过表达式动态访问对象的属性。 - `object?.method()`:调用对象的方法(如果存在)。 例如,访问嵌套对象中的属性: ```javascript const user = { profile: { name: 'John Doe' } }; // 使用可选链 const userName = user?.profile?.name; // 'John Doe' ``` 上述代码等价于传统的写法: ```javascript const userName = user && user.profile && user.profile.name; // 'John Doe' ``` 使用可选链可以显著减少冗余的条件判断,使代码更简洁易读[^4]。 --- ### 可选链与函数调用 可选链也适用于函数调用场景,尤其适合处理可选的回调函数或事件处理器。如果指定的方法存在,表达式将返回 `undefined` 而会引发错误。 ```javascript function invoke(fn) { fn?.call(this); // 如果 fn 存在,会报错 } ``` 这种写法比传统的条件判断更加简洁,并且避免了必要的错误处理逻辑[^5]。 --- ### 可选链与数组元素访问 除了对象属性之外,可选链也可以用于访问数组中的元素。如果数组本身为 `null` 或 `undefined`,或者索引超出范围,表达式会返回 `undefined`。 ```javascript const arr = [1, 2, 3]; console.log(arr?.[0]); // 1 console.log(arr?.[5]); // undefined ``` 这种方式可以有效防止访问未定义数组时的运行时错误[^5]。 --- ### 可选链空值合并运算符结合使用 为了进一步简化默认值的设置,可选链可以与空值合并运算符 `??` 结合使用。当左侧表达式的结果为 `null` 或 `undefined` 时,返回右侧的默认值。 ```javascript const obj = {}; const value = obj?.prop ?? 'default'; console.log(value); // 'default' ``` 这种组合在处理配置项、API 响应等确定结构的数据时非常有用[^4]。 --- ### 注意事项 虽然可选链提供了便捷的访问方式,但在使用时需要注意以下几点: - **可用于赋值**:能将可选链用于属性赋值操作,否则会导致语法错误。 ```javascript const obj = { propName: 'name' }; obj?.['propName'] = 'new name'; // SyntaxError ``` - **类型匹配仍会报错**:如果链中某个属性是函数但尝试以函数方式调用,依然会抛出错误。 ```javascript const obj = { method: 'not a function' }; obj?.method?.(); // TypeError: obj.method is not a function ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值