前言
let n = 0 if (n) {} let s = '' if (s.length) {} let v1 = undefined if (v1) {} // 通过 !! 运算符强转成 Boolean if (!!n) {} if (!!s) {} if (!!v1) {}
有时候我们想要得到一个明确的 Boolean 来进行判断/处理逻辑,我们可以通过
!!
或者!!+
运算符来强制转成 Boolean 类型,但是在不同的数据类型中,这两者的转换结果也会有所不同。
String
const strings = ['', ' ', 'a', '0', '1', '1a', '.', '.34', '0o123', '0b0101', '0xabc'] strings.forEach(element => console.log(element, !!element, !!+element))
打印结果如下表所示:
结论:对于 String 数据类型,空字符串时两者转换结果都为 false,但是在字符串长度不为空时,
!!
的转换结果则永远为 true,!!+
在数字类型字符串且不等于'0'
时为 true,其他情况均为 false(数字类型字符串表示合法的十进制、二进制、八进制、十六进制字符串)可以简单理解为:
!!
等价于 string.length > 0!!+
等价于 string.length > 0 && 是数字类型字符串 && string != ‘0’
Number
const numbers = [0, 1, 1.2, .3] numbers.forEach(element => console.log(element, !!element, !!+element))
打印结果如下表所示:
false false结论:对于 Number 类型数据两者转换结果保持一致,对于
0
则为false
,其他情况均为true
Boolean
const bools = [true, false] bools.forEach(element => console.log(element, !!element, !!+element))
打印结果如下表所示:
false false false结论:对于 Boolean 类型数据的转换结果和原始值保持一致
Null
const v = null console.log(v, !!v, !!+v)
打印结果如下表所示:
false false结论:对于 Null 类型数据两者转换结果均为
false
undefined
const v = undefined console.log(v, !!v, !!+v)
打印结果如下表所示:
undefined false false结论:对于 undefined 类型数据两者转换结果均为
false
NaN
const v = NaN console.log(v, !!v, !!+v)
打印结果如下表所示:
false false结论:对于 NaN 类型数据两者转换结果均为
false
Array
const values = [[], [1], [1, 2], ['1'], ['1', '2'], ['a'], ['a', 'b']] values.forEach(element => console.log(element, !!element, !!+element))
打印结果如下表所示:
false [1, 2] false [‘1’] [‘1’, ‘2’] false [‘a’] false [‘a’, ‘b’] false结论:对于 Array 数据类型,
!!
的转换结果永远为true
,而!!+
的转换结果对于有且只有一个元素,并且该元素是 Number 类型或纯数字类型字符串时结果为true
,其他情况均为false
Function
const func = () => {} console.log(func, !!func, !!+func)
打印结果如下表所示:
() = {} false结论:对于 Functionp 类型数据,
!!
的转换结果永远为true
,而!!+
的转换结果则永远为false
Object
const objs = [{}, { name: 'zhangsan' }] objs.forEach(element => console.log(element, !!element, !!+element))
打印结果如下表所示:
false {name: ‘zhangsan’} false结论:对于 Object 数据类型,
!!
的转换结果永远为true
,而!!+
的转换结果则永远为false
Symbol
const symbol = Symbol('Test') console.log(symbol) console.log(!!symbol) console.log(!!+symbol)
打印结果如下表所示:
Symbol(Test) TypeError: Cannot convert a Symbol value to a number结论:对于 Symbol 数据类型,
!!
的转换结果永远为true
,而!!+
的转换会抛出异常
结果
对于
String 空字符串时为 false,其他情况为 true 数字类型字符串且不等于!!
和!!+
这两个运算符的转换结果,汇总如下表:'0'
时为 true,其他情况为 false Number 0 为 false, 其他情况均为 true 0 为 false, 其他情况均为 true Boolean 和旧值保持一致 和旧值保持一致 false false undefined false false false false Array 当数组只有一个元素且元素为 Number 或 数字类型字符串为 true,其他情况为 false Function false Object false Symbol 抛异常(TypeError: Cannot convert a Symbol value to a number)数字类型字符串表示由数字和单个点号组成的字符串(即合法的十进制、二进制、八进制、十六进制字符串),如:123、1.2、.34、0o12、0b01、0x123abc 均为合法格式;1a、1.2.3 这种则为不合法格式 !!
和!!+
两者转换只在 String/Array/Function/Object/Symbol 这几个数据类型中存在差异,其他数据类型的转换结果两者都保持一致!!+
是由双重逻辑非(!!)和一元加法(+)两种运算符组合而成,但是一元加法的优先级比逻辑非的优先级要高,所以会先进行一元加法的运算,再进行双重逻辑非的运算,理解了优先级,那么这个转换结果就取决于一元加法了,因为一元加法会尝试将数据转成 Number 类型,转换失败时会返回 NaN,具体可以参考文档说明对于使用
!!
还是!!+
你可以对照上表的结果结合项目实际情况考虑吧,可以简单理解为!!
是不严格的,!!+
是更加严格的,我平时都是使用!!
,只是在偶然间看到有人使用!!+
。Boolean