本文旨在讓讀者能更加清晰地了解 “空物件 {}” 與 “空陣列 ()” 相加(eg:“[] + []” 、“[] + {}”、“{} + []”、“{} + {}”)得到結果的隱式轉換程序,還望讀者能仔細閱讀完,相信或多或少會有所識訓 !
首先來了解一些相關知識
一、在 JavaScript 中,一共有兩種型別的值:
- 原始值(primitives)
undefined、null、boolean、number、string - 物件值(objects)
除了原始值外,其他的所有值都是物件型別的值,包括陣列(array)和函式(function),
二、“加號 +” 的運算原理( “+” 既是一元運算子,也是二元運算子)
1. 一元運算子
說明:’+’ 號運算子作為一元運算子時,運算式將進行 ToNumber() 操作,
① ToNumber(argument) 轉換方式:
| argument型別 | 回傳值 |
|---|---|
| Undefined | return NaN |
| Null | return 0 |
| Boolean | true return 1; false return 0; |
| Number | return value |
| String | 若字串為純數字,回傳轉換后的數字;非純數字則回傳 NaN |
| Symbol | 拋出 TypeError 例外 |
| Object | 進行如右步驟:1.先進行 ToPrimitive(argument, hint Number) 得到 rs ;?2.然后回傳 ToNumber(rs) 的結果, |
② 示例:
// Undefined
+ undefined; // => NaN
// Null
+ null; // => 0
// Boolean
+ true; // => 1
+ false; // => 0
// String
+ '1'; // => 1
+ '-1'; // => -1
+ 'a1'; // => NaN
// Object
+ []; // => 0
+ {}; // => NaN
+ { valueOf: function () { return 0 } }; // => 0
/*
* 該物件重寫了 valueOf() 方法,
* 因此該物件隱式轉換程序中呼叫 valueOf() 方法后得到 0,
* 故最終結果為 0
*/
2. 二元運算子
① 運算元其一為字串(String)
??運算元其一為字串時,進行字串的拼接操作,
console.log('10' + 1); // 101
console.log('ab' + 'cd'); // abcd
console.log('1' + true); // 1true
console.log('1' + undefined); // 1undefined
console.log('1' + null); // 1null
② 運算元其一為數字(Number)
??1 + ‘cd’ 為運算元其一為字串情況,做字串拼接操作;其余為在沒有字串情況下,運算元其一為數字,做型別轉換后做數值相加,
console.log(1 + 1); // 2
console.log(1 + 'cd'); // 1cd
console.log(1 + true); // 2
console.log(1 + undefined); // NaN
console.log(1 + null); // 1
注:在運算元一側為數字,另一側為字串的情況下,如果是 “減號 - ” 或其他運算子(eg:“*”、“/”、“%”、“ >”、“<”、“==”) 的話,會將字串轉換為數字進行減法操作(eg:數字相減:10 - “1” = 9),
③ 數字(Number) / 字串(String) 以外的原始型別相加
??當數字與字串以外的其他原始資料型別直接使用加號運算時,要先轉為數字(可參考上面有關 “ToNumber(argument) 轉換方式” 的表格)再運算,這與字串完全無關,
console.log(true + true); // 2
console.log(true + null); // 1
console.log(true + undefined); //NaN
console.log(undefined + null); //NaN
console.log(undefined + undefined); //NaN
console.log(null + null); //0
④ 運算元其一為復雜資料型別(以下為初步解釋,示例請見后續第三大點)
注意,以上 ① ~ ③ 的示例均是原始資料型別的 “加法 +” 操作,當進行復雜資料型別的 “加法 +” 操作時,JS 內部有以下有隱式轉換程序(實際上是 JS 呼叫了內部的 toPrimitive() 方法,有關該方法詳見 JS原始值轉換演算法—toPrimitive() ):
??Ⅰ 當 “加號 +” 的某一側資料型別是物件時,會將物件先進行 valueOf() 操作(有關 valuOf() 方法可參考博文 JS 中 valueOf() 方法的詳解);
??Ⅱ 如果回傳的是原始資料型別,則后續操作按照以上三點進行;
??Ⅲ 如果回傳的值還是物件,則再呼叫 toString 方法(此處應了解 “ [] 呼叫 toString() 方法變成空字串 "",{} 呼叫 toString() 等于 [object Object] ” ,有關 toString 方法詳解可參考 有關 toString() 方法的初步認識 );
??Ⅳ 若回傳原始資料型別,則按照上面原始資料型別計算;
??Ⅴ 否則報錯,
⑤ 有關 NaN 需要注意的點
??Ⅰ. 執行運算時 , 非帶 “+” 號的運算,只要有 NaN 參與,執行結果就都是 NaN;
??Ⅱ. 如果是帶 “+” 號的運算,一側是 NaN、另一側是字串時,就執行字串拼接操作;
??Ⅲ. 如果是帶 “+” 號的運算,一側是 NaN、另一側是 Number 型別的數值時,執行結果就都是 NaN;
??Ⅳ. 在 JavaScript 中的規定,NaN 表示的是非數字,但是這個非數字也是不同的;因此 NaN 不等于 NaN,兩個 NaN 永遠不可能相等,
注:NaN 雖然不是一個具體數值,但資料型別確是 Number 型別;NaN 和任何 Number 型別資料進行 “+”、“-”、“*”、“/”、“% 等操作時,操作結果都是 NaN,
三、“空物件 {}” 與 “空陣列 []” 的相加問題
1. 空陣列 + 空陣列

隱式轉換程序: 首先 [] 呼叫 valueOf() 方法,得到的還是 [],然后呼叫 toString() 方法,得到 "",兩個 "" 相加還是 "",故最終結果為 "",
2. 空陣列 + 空物件

隱式轉換程序: 如第一點分析,[] 經隱式轉換最終得到 "";{} 呼叫 valueOf() 方法,得到的還是 {},然后呼叫 toString() 方法,得到 "[object Object]","" 和 "[object Object]" 相加得到 "[object Object]",故最終結果為 "[object Object]",
3. 空物件 + 空物件

隱式轉換程序: 分析與上面類似,此處不再累贅
4. 空物件 + 空陣列

補充有關知識:
??首先要知道 javascript 有這樣的特性,如果 {} 既可以被認為是代碼塊,又可以被認為是物件字面量,那么 js 會把他當做代碼塊;
??而在瀏覽器中,如果 {} 在前面,而 [] 在后面時,前面的 {} 會被認為是區塊陳述句而不是物件字面量;
??故此處的 {} + [] 可看成 + [],然后參考上面有關 “ToNumber(argument)轉換方式” 的表格中 argument 型別為 Null 和 Object 的兩行,對本例進行分析,
隱式轉換程序:
??① 參考表格中 argument 型別為 Object 的一行,對于 + [] 來說,對 [] 進行 ToPrimitive(argument, hint Number) 操作【可參考第二大點的第二小點最下方的注釋】,先對 [] 呼叫 valueOf() 方法,得到的還是 [],然后呼叫 toString() 方法,得到 "";
??② 參考表格中 argument 型別為 Null 的一行,故 + "" 回傳的是 0 ,
?綜上,最終 {} + [] 得到的結果是 0
5. !空陣列 + 空陣列

補充有關知識:

??根據運算子優先級 , ! 的優先級是大于 + 的,所以先會執行 ![] ;
??! 可將變數轉換成 boolean 型別,且除 null、undefined、NaN 以及 "" 取反為 true 外,其余運算元取反都為 false ,
隱式轉換程序:
??① 根據以上分析,先執行 ![] ,得到 false
??② [] 經隱式轉換最終得到 ""
??③ 參考第二大點的第二小點中的示例(如下),可知 false + "" 的結果為 "false"
console.log('1' + true); // 1true
6. !空陣列 + 空物件

隱式轉換程序:
??① 執行 ![] ,得到 false
??② {} 經隱式轉換得到 "[object Object]"
??③ 可知 false + "[object Object]" 的結果為 "false[object Object]"
7. !空物件 + 空物件

隱式轉換程序:
??① 執行 !{} ,得到 false
??② {} 經隱式轉換得到 "[object Object]"
??③ 可知 false + "[object Object]" 的結果為 "false[object Object]"
8. !空物件 + 空陣列

隱式轉換程序:
??① 執行 !{} ,得到 false
??② [] 經隱式轉換得到 ""
??③ 可知 false + "" 的結果為 "false"
整理不易,本文各方面講的比較詳細,也附上了有關知識的鏈接,如果各位讀者讀完本文章覺得有識訓的話,還望點個贊,萬分感謝 ! ! ! ! !
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/295421.html
標籤:其他
上一篇:JQuery基礎操作超詳解?
下一篇:react入門教程
