1. 程式人生 > 實用技巧 >“+”號運算子的深入理解(javascript)

“+”號運算子的深入理解(javascript)

這個符號相信我們大家都不陌生,但是在面試中很容易遇到這個符號的各種騷操作問題,接下來我們就來深入理解分析下這個運算子是怎麼考倒我們的。

let n = "10",
    m = 10;

console.log(10 + n); //'1010'  示例一 "+"有一邊出現字串「前提:有兩邊」 則是字串拼接‘1010’
console.log(+n); // 10  示例二  “+”只有一邊,把字串轉為數字 10
console.log(++n); // 11  示例三  “++”和上面一樣的,只是會自身累加1
  // i = i+1 i+=1 這兩者一樣
  // ++i i++ 大部分情況和上面一致,如果i是字串則和上面不一致「上面會處理成字串拼接,下面是數學累加」

let res = {} + m;
console.log(res); //[object object]10  示例四
console.log(m + {}); //10[object object]  示例五
console.log(m + new Number(10)); //20  示例六
console.log(m + { name: 10 }); //10[object object]  示例七
console.log({} + m); //[object object]10  示例八

上面用幾個比較典型的用法作為示例,那麼下面我們來分析總結一下:

  • 前提:"+" 只有一邊
    • 會把字串轉為數字 比如示例二、示例三
  • 前提:"+" 有兩邊
    • "+" 有一邊出現字串,則是字串拼接 比如示例一
    • "+" 有一邊是物件,可能會是字串拼接
      • 比如:上面的示例四、五、10+{} / 10+{name:11} -> '10[object object]' 、10+[10,20,30] -> '1010,20,30'
      • 特殊情況:
        • 10+new Number(10) -> 20 因為物件沒參與運算,瀏覽器認為物件只是個程式碼塊,只計算+10
        • {}+10/{name:10}+10 -> 10 在consle直接輸出就是數字10,和上面原因一樣
        • 但下面這種情況也是字串拼接,因為從語法分析來講物件參與運算了,就先把物件轉成字串
        • ({}+10)-> '[object object]10' let x = {} + 10; x -> '[object object]10' 這也就是為什麼上面程式碼塊裡的示例七、八會是字串拼接的原因

上面的總結分析都是在我自己去測試發現的,如果想要真正的搞明白那就肯定得知道物件在做數學運算的時候底層原理機制:

  • 首先檢測物件的 Symbol.toPrimitive 這個屬性值,如果有則基於這個值進行計算,如果沒有
  • 檢測物件的 valueOf() 這個值「原始值:基本型別值」,如果有則基於這個值進行計算,如果沒有
  • 就獲取物件的 toString() 把其變成字串,遇到了“+”就是字串拼接

我們是可以改寫物件的Symbol.toPrimitive 這個屬性值的,具體怎麼操作我們來看看下面的程式碼。

let obj = {
  [Symbol.toPrimitive](hint) {
    //hint是瀏覽器識別出來的型別,有三個值 string/bumber/default
    if (hint === "string") {
      return "holle";
    }
    if (hint === "number") {
      return 2;
    }
    return null;
  },
};
console.log(+obj);  //2
console.log(`${obj}`); //"holle"
console.log(obj + "10"); //"null10"