在JS开发中,我们经常需要根据条件决定变量赋值或返回值。if...else语句固然可以实现,但代码会显得冗长。这时三元运算符(ternary operator)就能大显身手——它用单行代码就能完成条件判断,是JS中最简洁的条件表达式写法。
我第一次接触这个语法是在重构一个表单验证函数时。原本15行的if嵌套用三元运算符压缩到3行,不仅可读性更好,执行效率也提升了。下面通过具体案例带你掌握这个"条件表达式之王"的完整用法。
javascript复制condition ? exprIfTrue : exprIfFalse
这个语法结构包含三个核心部分:
condition:任何可以转换为布尔值的表达式exprIfTrue:当condition为truthy时执行的表达式exprIfFalse:当condition为falsy时执行的表达式:前的表达式:后的表达式关键细节:三元运算符总会返回一个值,这与if语句有本质区别。这意味着它可以直接用在赋值语句右侧。
最典型的用法,比if语句简洁得多:
javascript复制// 传统写法
let accessLevel;
if (user.isAdmin) {
accessLevel = 'admin';
} else {
accessLevel = 'user';
}
// 三元运算符写法
const accessLevel = user.isAdmin ? 'admin' : 'user';
在动态生成HTML时特别实用:
javascript复制const itemHTML = `
<div class="alert alert-${hasError ? 'danger' : 'success'}">
${hasError ? errorMessage : '操作成功'}
</div>
`;
虽然可行,但建议不超过两层:
javascript复制const grade = score >= 90 ? 'A'
: score >= 80 ? 'B'
: score >= 70 ? 'C'
: 'D';
经验提示:当嵌套超过两层时,建议改用if...else或switch语句,否则会降低可读性。
利用逻辑与的特性,可以写出更简洁的代码:
javascript复制// 仅当user存在时才取name属性
const userName = user ? user.name : 'Guest';
// 等效写法
const userName = user && user.name || 'Guest';
在React等框架中很常见:
jsx复制const Button = ({ isPrimary }) => (
<button className={isPrimary ? 'btn-primary' : 'btn-default'}>
{isPrimary ? '主要操作' : '次要操作'}
</button>
);
通过jsPerf测试可以发现:
javascript复制// 错误1:忘记返回值
const result = condition ? console.log('true') : console.log('false');
// 错误2:误用语句而非表达式
const value = condition ? let x = 1 : let y = 2;
javascript复制const permission = user.isAdmin
? 'full-access'
: user.isSubscriber
? 'partial-access'
: 'read-only';
javascript复制const price = (isMember && discount)
? basePrice * 0.8
: basePrice;
在三元运算中,TS能自动推断出最窄类型:
typescript复制const maybeString: string | null = Math.random() > 0.5 ? 'hello' : null;
// TS知道这里maybeString的类型是 string | null
| 特性 | 三元运算符 | if...else |
|---|---|---|
| 返回值 | 必有返回值 | 无返回值 |
| 可读性 | 简单条件优 | 复杂条件优 |
| 性能 | 微优势 | 稍慢 |
| 调试难度 | 较难 | 容易 |
当只需要处理falsy值时的简化写法:
javascript复制// 三元写法
const backupValue = value ? value : defaultValue;
// 逻辑或写法
const backupValue = value || defaultValue;
ES2020的新特性组合:
javascript复制const street = user.address?.street || '未填写';
javascript复制const authorizationLevel = user.isSuperAdmin ? 'super-admin'
: user.isAdmin ? 'admin'
: 'normal';
推荐配置:
json复制{
"rules": {
"no-nested-ternary": "warn",
"no-unneeded-ternary": "error",
"multiline-ternary": ["error", "always-multiline"]
}
}
所有现代浏览器完全支持,包括:
三元运算符的优先级较低(4),常见情况:
javascript复制// 等效于 (a && b) ? c : d
a && b ? c : d
// 需要先计算三元运算结果时用括号
a * (b ? c : d)
可以作为纯函数的一部分:
javascript复制const getDiscount = isVIP => isVIP ? 0.2 : 0.1;
在实际项目中,我通常会在这些场景优先使用三元运算符:
而对于复杂的业务逻辑,特别是需要多个语句块时,还是会选择if...else结构。记住:代码的可维护性永远比简洁性更重要。