为什么在JavaScript中对布尔值使用对象展开语法可以生效?
JavaScript对象展开结合逻辑与操作的运行原理
首先明确:你观察到的效果不是「对布尔值使用对象解构/展开」的特性,而是逻辑与短路求值规则 + 对象展开语法对原始值的处理规则两个特性共同作用的结果。
1. 逻辑与&&的短路求值规则
JavaScript中&&运算符遵循短路求值逻辑:
- 当左侧操作数为假值时,直接返回左侧操作数的值,不会执行右侧表达式
- 当左侧操作数为真值时,返回右侧操作数的值
对应你的示例:
true && toto左侧为真值,返回toto对象(不是布尔值)false && toto左侧为假值,返回false布尔值
2. 对象展开...的规范处理逻辑
ES2018引入的对象展开语法,对...后跟随的值有明确的处理规则:
- 如果值为
null或undefined,直接忽略,不添加任何属性 - 如果值为原始类型(布尔值、数字、字符串等),会先转换为对应的包装对象,再提取所有可枚举自有属性添加到目标对象中
- 布尔值、数字的包装对象没有任何可枚举的自有属性,所以展开后不会添加任何属性,相当于被忽略
- 字符串的包装对象有可枚举的索引属性,所以展开
...'abc'会得到{0:'a',1:'b',2:'c'}
示例运行过程拆解
第一个示例
const other = { other: 'other', ...condition && toto }
运算顺序:先计算condition && toto得到toto对象,再展开toto对象,将name:'toto'属性添加到新对象中,最终结果符合预期。
第二个示例
const otherWithoutToto = { other: 'other', ...falseCondition && toto }
运算顺序:先计算falseCondition && toto得到布尔值false,展开false时没有可枚举属性可添加,相当于没有额外属性,最终对象只有other属性。
额外验证
你可以直接测试以下代码确认规则:
// 展开布尔值、数字、null、undefined都不会产生属性 console.log({ ...false, ...123, ...null, ...undefined }) // 输出 {} // 只有字符串、普通对象等有可枚举属性的值才会生效 console.log({ ...'test', ...{a:1} }) // 输出 {0:'t',1:'e',2:'s',3:'t',a:1}
内容的提问来源于stack exchange,提问作者Flyos91
相关产品推荐
相关产品推荐

