JS直譯器之自動型別轉換:[]==![]
自動型別轉換
自動型別轉換主要針對的是物件型別,有倆種情況會出現:
-
等性運算(
==
,即比較,如:false == []) -
四則運算(
+-*/
,如:[] + 1)
在這兩種運算中,js直譯器需要將物件型別轉換成原始型別(除了null
與undefined
),才能進行後續的操作。
在說明自動型別轉換前,首先要了解兩個方法:
-
Object.prototype.toString
-
Object.prototype.valueOf
這兩個方法定義在Object.prototype
上,是轉換的核心
物件=>數字
在用物件做四則運算時,JS直譯器會嘗試將其轉換成數字
比如下面這種操作:
let obj = {};
obj + 1;
直譯器會進行如下操作
let obj = {};
let temp = 0;
if(typeof obj.valueOf() != `object`){
temp = obj.valueOf();
}else if(typeof obj.toString() != `object`){
temp = obj.toString();
}else{
throw new Error("Uncaught TypeError: Cannot convert object to primitive value...")
}
temp + 1; // "[object object]1"
用語言描述其過程:
-
呼叫valueOf(),返回值若不是原始型別,執行2
-
呼叫toString(),返回值若不是原始型別,執行3
-
丟擲錯誤:
Uncaught TypeError: Cannot convert object to primitive value(…)
下面來幾個例項測試下:
僅呼叫 valueOf
let obj = {};
obj + 1; // "[object Object]1"
obj.valueOf = () => {
return 0;
}
obj.toString = () => {
return -1;
}
obj + 1; // 1
呼叫valueOf
與toString
let obj = {};
obj.valueOf = () => {
return {};
}
obj.toString = () => {
return -1;
}
obj + 1; // 0
var obj = {};
物件=>字串
直接輸出一個物件時,JS直譯器會嘗試將其轉為字串
比如下面的程式碼:
let obj = {};
alert(obj);
直譯器會進行如下操作:
let obj = {};
let temp = "";
if(typeof obj.toString() != `object`){
temp = obj.toString();
}
else if(typeof obj.valueOf() != `object`){
temp = obj.valueOf();
}
else{
throw new Error("Uncaught TypeError: Cannot convert object to primitive value(…)")
}
console.log(temp);
上面的步驟用語言描述就是:
-
呼叫toString(),返回值若不是原始型別,執行2
-
呼叫valueOf(),返回值若不是原始型別,執行3
-
丟擲錯誤:” Uncaught TypeError: Cannot convert object to primitive value(…)”
恰恰與轉換成數字的呼叫順序相反
同樣用例項測試下:
僅呼叫toString
let obj = {};
obj.toString = () => {
return "hi";
}
obj.valueOf = () => {
return "hello"
}
alert(obj); // "hi"
呼叫toString
與valueOf
// 呼叫 toString() 與 valueOf()
let obj = {};
obj.toString = () => {
return {};
}
obj.valueOf = () => {
return "hello"
}
alert(obj); // "hello"
等性運算 ==
在進行==
比較時,不同型別的比較一般會都會轉換成數字來進行
比如:[] == false
=> 0 == 0
=> true
其中又有些特殊情況
比如:
-
NaN == NaN
=>false
-
null == undefined
=>true
參考博文
相關文章
- (譯)js中的神奇的型別轉換JS型別
- js型別轉換JS型別
- Java資料型別自動轉換(++ ,+=)Java資料型別
- Js型別轉換之相等運算子[初級]JS型別
- java基本資料型別與自動轉換Java資料型別
- JS資料型別的轉換JS資料型別
- JS中資料型別轉換JS資料型別
- 強制型別轉換之(==)型別
- JS 型別轉換,小嚐一口JS型別
- JS裡的資料型別轉換JS資料型別
- 你可能忽略的js型別轉換JS型別
- JS 裡的資料型別轉換JS資料型別
- 附一張js的型別轉換JS型別
- JS資料型別轉換規則JS資料型別
- Javascrip 之 字串處理 & 定時器 & 型別轉換Java字串定時器型別
- Node.js REPL(互動式直譯器)Node.js
- js資料型別間的互相轉換JS資料型別
- JS在if中的強制型別轉換JS型別
- C++ 動態型別轉換C++型別
- 09.AutoMapper 之自定義型別轉換器(Custom TypeAPP型別
- 型別轉換型別
- 【C++】C++之型別轉換C++型別
- 自學PHP筆記 (三) 型別轉換PHP筆記型別
- 自學PHP筆記(三) 型別轉換PHP筆記型別
- java- 型別-轉換:基本型別以及包裝型別的轉換Java型別
- Mybatis實踐(一)型別轉換器MyBatis型別
- WPF 型別轉換器的實現型別
- 資料型別,型別轉換資料型別
- c語言中的資料型別的自動轉換原則C語言資料型別
- 型別轉換(cast)型別AST
- Convert型別轉換型別
- Map和String型別之間的轉換型別
- 013 Rust死靈書之型別轉換Rust型別
- [Java基礎]之 資料型別轉換Java資料型別
- [譯] [1] + [2] - [3] === 9!? 型別轉換深入研究型別
- jsp頁面number型別自動轉為String型別JS型別
- 自學java筆記I 基本型別+轉義字元+資料型別的轉換Java筆記字元資料型別
- JS中的資料型別轉換:String轉換成Number的3種方法JS資料型別
- 「 giao-js 」用js寫一個js直譯器JS