JS解释器之自动类型转换:[] == ![]

自动类型转换

自动类型转换主要针对的是对象类型,有俩种情况会出现:

  • 等性运算(==,即比较,如: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

参考博文

上一篇:微信短网址在线生成 推荐几个可在在线生成微信短网址的平台


下一篇:同步多域名dig