JS直譯器之自動型別轉換:[]==![]

烽穹寒淵發表於2016-10-13

自動型別轉換

自動型別轉換主要針對的是物件型別,有倆種情況會出現:

  • 等性運算(==,即比較,如:false == [])

  • 四則運算(+-*/,如:[] + 1)

在這兩種運算中,js直譯器需要將物件型別轉換成原始型別(除了nullundefined),才能進行後續的操作。

在說明自動型別轉換前,首先要了解兩個方法:

  • 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"

用語言描述其過程:

  1. 呼叫valueOf(),返回值若不是原始型別,執行2

  2. 呼叫toString(),返回值若不是原始型別,執行3

  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

呼叫valueOftoString

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);

上面的步驟用語言描述就是:

  1. 呼叫toString(),返回值若不是原始型別,執行2

  2. 呼叫valueOf(),返回值若不是原始型別,執行3

  3. 丟擲錯誤:” Uncaught TypeError: Cannot convert object to primitive value(…)”

恰恰與轉換成數字的呼叫順序相反

同樣用例項測試下:

僅呼叫toString

let obj = {};
obj.toString = () => {
    return "hi";
}
obj.valueOf = () => {
    return "hello"
}
alert(obj); // "hi"

呼叫toStringvalueOf

// 呼叫 toString() 與 valueOf()
let obj = {};
obj.toString = () => {
    return {};
}
obj.valueOf = () => {
    return "hello"
}
alert(obj); // "hello"

等性運算 ==

在進行==比較時,不同型別的比較一般會都會轉換成數字來進行

比如:[] == false => 0 == 0 => true

其中又有些特殊情況

比如:

  • NaN == NaN => false

  • null == undefined => true

參考博文


相關文章