JavaScript:问号?的多种用法

文章目录

条件运算符 (三元运算符)

早在ES1(ECMAScript 1st Edition)中就已经存在

复制代码
let value = a > b ? exprIfTrue : exprIfFalse;
//为真,则返回 exprIfTrue 的值;否则返回 exprIfFalse 的值

可选链操作符 (?.)

ES2020(ECMAScript 2020)

复制代码
obj?.propName;
//当尝试访问嵌套对象的属性时,如果 obj 是 null 或 undefined,则表达式将立即返回 undefined
//而不会抛出错误。这个操作符用于安全地访问可能不存在的对象属性或方法。

空值合并操作符 (??)

ES2020(ECMAScript 2020)

复制代码
value ?? defaultValue;
//如果 value 不是 null 或 undefined,则返回 value;否则返回 defaultValue。
//该操作符用于提供一个默认值,当变量可能为空值时。

逻辑赋值运算符(??= )

ES2021(ECMAScript 2021)

??=(空值合并赋值) 这个运算符仅当左侧表达式的值为 null 或 undefined 时才执行右侧的赋值操作

复制代码
let preference = localStorage.getItem('language');
preference ??= 'en'; 

// 如果从localStorage获取的语言偏好存在且非null/undefined,则使用该偏好;
// 否则将默认语言设置为'en'。

let value;
value ??= "fallbackValue"; // 因为 value 为 undefined,所以将 "fallbackValue" 赋给 value;现在 value = "fallbackValue"

let anotherValue = null;
anotherValue ??= "defaultValue"; // 因为 anotherValue 为 null,所以将 "defaultValue" 赋给 anotherValue;现在 anotherValue = "defaultValue"

补充:(&&=、||=)

&&=(逻辑与赋值) 这个运算符仅当左侧表达式的布尔值为真时才执行右侧的赋值操作。

复制代码
let count = 0;
count &&= someCondition ? valueIfTrue : 0;
// 如果 someCondition 为真并且有值,则将 valueIfTrue 赋给 count;
// 否则 count 的值不变。

let x = null;
x &&= 5; // 因为 x 为 false,所以不执行赋值,x 保持原值 null

let y = {value: 1};
y.value &&= 3; // 因为 y.value 为 true(即非 null 和 undefined),所以 y.value 被赋值为 3,现在 y = {value: 3}

||=(逻辑或赋值) 这个运算符仅当左侧表达式的布尔值为假时才执行右侧的赋值操作。

复制代码
let userSetting = localStorage.getItem('theme') || 'default';
userSetting ||= 'dark';

// 如果从localStorage获取到的主题存在且非空字符串,则使用该主题;
// 否则将默认主题设置为'dark'。

let color = "";
color ||= "blue"; // 因为 color 为空字符串(falsy),所以将 "blue" 赋给 color;现在 color = "blue"

let enabled = false;
enabled ||= true; // 因为 enabled 为 false,所以将 true 赋给 enabled;现在 enabled = true

正则表达式中

1、量词:匹配零次或一次 在正则表达式模式中,? 可以放在一个字符、字符集或元字符后面,表示前面的元素可以出现0次或者1次。

复制代码
let regex = /a?b/;
let str = "ab";
console.log(str.match(regex)); // 输出:["ab"]

str = "b";
console.log(str.match(regex)); // 输出:["b"]

2、非贪婪量词:当 ? 与量词 {n, m} 或 {n,} 结合使用时,它变为非贪婪版本,尽可能少地匹配字符。

复制代码
et regex = /.*?abc/g;
let str = "Hello abc world abc!";
console.log(str.match(regex)); // 输出:["abc", "abc"]

(.) 表示任何字符,(*?) 表示匹配任意数量的字符但尽可能少匹配,所以每次只匹配到第一个 "abc" 前的最短字符串。

3、非捕获组:当 ? 放在括号 () 开头时,形成 (?:pattern)? 形式的非捕获组,这个组不计入返回结果中,并且不会被捕获供后续引用。

复制代码
let regex = /(?:ab)?c/;
let str = "ac";
console.log(str.match(regex)); // 输出:["c"]
相关推荐
被摘下的星星5 分钟前
Java的类加载
java·开发语言
skilllite作者8 分钟前
SkillLite 多入口架构实战:CLI / Python SDK / MCP / Desktop / Swarm 一页理清
开发语言·人工智能·python·安全·架构·rust·agentskills
秋月的私语14 分钟前
遥感影像拼接线优化工具:基于Qt+GDAL+OpenCV的从零到一实践
开发语言·qt·opencv
A923A19 分钟前
【从零开始学 React | 第四章】useEffect和自定义Hook
前端·react.js·fetch·useeffect
xwz小王子22 分钟前
智元发布 GO-2:动作空间推理 + 全生命周期闭环,让机器人稳定可靠落地
开发语言·golang·机器人
charlie11451419122 分钟前
通用GUI编程技术——图形渲染实战(二十八)——图像格式与编解码:PNG/JPEG全掌握
开发语言·c++·windows·学习·图形渲染·win32
ZC跨境爬虫23 分钟前
批量爬取小说章节并优化排版(附完整可运行脚本)
前端·爬虫·python·自动化
ZC跨境爬虫25 分钟前
海南大学交友平台登录页开发实战day4(解决python传输并读取登录信息的问题)
开发语言·前端·python·flask·html
wjs202428 分钟前
SQL LEN() 函数详解
开发语言
来一颗砂糖橘28 分钟前
pnpm:现代前端开发的高效包管理器
前端·pnpm