1.++i
和i++
这两种操作符在被称为前缀和后缀版的递增(/递减)操作符。
对于前缀递增操作符,它的包含 2 层含义:
- 作为语句,使得 i 的为 i+1。
- 作为表达式,它的值为 i+1。
对与后缀表达式,它作为语句时和前缀版没有差别,但是作为表达式时,它的值为 i。
2.||
和&&
这两个操作符都会进行隐式toBoolean
转换a || b
表达式的值如下面的代码所示。
if(aBool) return a;
retur b;
这个表达式和 ?? 相似,但是它会进行类型转换,因此是 ?? 的超集。a && b
表达式的值如下面的代码所示。
if (aBool) return b;
return a;
3.==
这个操作符可能对两边的操作数进行隐式类型转换。规则如下:
- null 和 undefined 不进行隐式类型转换,且规定 null == undefined 为 true。
- 任一操作数为 Boolean 或 Number 类型,则将两个操作数都进行 toNumber 操作后进行数值比较(NaN 不等于任何值)。(对于 Object 类型,没有 preferedType)
- 这 2 个操作数是 String 和 Object 类型的组合,则对 Object 类型的操作数进行 toString 操作,之后进行字符串比较。
-
4.
nullist
操作符 空值合并运算符
??
a ?? b
表达式的值等同于如下代码a === undefined || a === null ? b : a;
可选链式操作符
?.
obj?.prop1?.prop2?.prop3 表达式的值等同于如下代码。
function getValue() {
if (obj.prop1) {
if (obj.prop1.prop2) {
if (obj.prop1.prop2.prop3) {
return obj.prop1.prop2.prop3;
}
return;
}
return;
}
return;
}
经典问题:
a == 1 && a == 2 && a == 3
为 true,求 a 的值。
解法一 : 隐式转换重写 valueOf() / toString()
`a == 1 && a == 2 && a == 3
,若 a
为一个对象,那么 a
与数字类型之间的比较就会触发 valueOf()
方法,若此方法返回还是返回一个对象,则继续调用 toString()
方法,所以我们重写 valueOf()
或者 toString()
方法都可行。
let a = {
i: 1,
valueOf() {
return this.i++
}
}
if (a == 1 && a == 2 && a == 3) {
console.log(a)
}
解法二: Object.defineProperty()
var value = 0;
Object.defineProperty(window, 'a', {
get: function() {
return this.value += 1;
}
});
console.log(a===1 && a===2 && a===3) // true
解法三: 改写join
方法
var a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3)