1.++ii++

这两种操作符在被称为前缀和后缀版的递增(/递减)操作符。
对于前缀递增操作符,它的包含 2 层含义:

  1. 作为语句,使得 i 的为 i+1。
  2. 作为表达式,它的值为 i+1。

对与后缀表达式,它作为语句时和前缀版没有差别,但是作为表达式时,它的值为 i。

2.||&&

这两个操作符都会进行隐式toBoolean转换
a || b表达式的值如下面的代码所示。

  1. if(aBool) return a;
  2. retur b;

这个表达式和 ?? 相似,但是它会进行类型转换,因此是 ?? 的超集。
a && b 表达式的值如下面的代码所示。

  1. if (aBool) return b;
  2. return a;

3.==

这个操作符可能对两边的操作数进行隐式类型转换。规则如下:

  1. null 和 undefined 不进行隐式类型转换,且规定 null == undefined 为 true。
  2. 任一操作数为 Boolean 或 Number 类型,则将两个操作数都进行 toNumber 操作后进行数值比较(NaN 不等于任何值)。(对于 Object 类型,没有 preferedType)
  3. 这 2 个操作数是 String 和 Object 类型的组合,则对 Object 类型的操作数进行 toString 操作,之后进行字符串比较。
  4. 这 2 个操作数都是 Object 类型,则比较的是引用。

    4.nullist操作符

  5. 空值合并运算符??

    a ?? b表达式的值等同于如下代码 a === undefined || a === null ? b : a;

  6. 可选链式操作符?.

    obj?.prop1?.prop2?.prop3 表达式的值等同于如下代码。

  1. function getValue() {
  2. if (obj.prop1) {
  3. if (obj.prop1.prop2) {
  4. if (obj.prop1.prop2.prop3) {
  5. return obj.prop1.prop2.prop3;
  6. }
  7. return;
  8. }
  9. return;
  10. }
  11. return;
  12. }

经典问题:

a == 1 && a == 2 && a == 3 为 true,求 a 的值。

解法一 : 隐式转换重写 valueOf() / toString()

`a == 1 && a == 2 && a == 3,若 a为一个对象,那么 a 与数字类型之间的比较就会触发 valueOf() 方法,若此方法返回还是返回一个对象,则继续调用 toString()方法,所以我们重写 valueOf()或者 toString()方法都可行。

  1. let a = {
  2. i: 1,
  3. valueOf() {
  4. return this.i++
  5. }
  6. }
  7. if (a == 1 && a == 2 && a == 3) {
  8. console.log(a)
  9. }

解法二: Object.defineProperty()

  1. var value = 0;
  2. Object.defineProperty(window, 'a', {
  3. get: function() {
  4. return this.value += 1;
  5. }
  6. });
  7. console.log(a===1 && a===2 && a===3) // true

同样的也可以使用proxy

解法三: 改写join方法

  1. var a = [1,2,3];
  2. a.join = a.shift;
  3. console.log(a == 1 && a == 2 && a == 3)

解法四: 隐藏字符