
四种转换总览

ToPrimitive
作用
将对象类型转换为原始类型
语法
ToPrimitive(obj,type)
type不同值的说明
type为string:
1.先调用obj的toString方法,如果为原始值,则return,否则进行第2步
2.调用obj的valueOf方法,如果为原始值,则return,否则进行第3步
3.抛出TypeError 异常
type为number:
1.先调用obj的valueOf方法,如果为原始值,则return,否则进行第2步
2.调用obj的toString方法,如果为原始值,则return,否则第3步
3.抛出TypeError 异常
type参数为空
1.该对象为Date,则type被设置为String
2.否则,type被设置为Number
ToPrimitive总结
ToPrimitive转成何种原始类型,取决于type,type参数可选。
若指定,则按照指定类型转换。
若不指定,默认根据实用情况分两种情况,Date为string,其余对象为number。
ToString
作用
将其他类型转换为字符串类型
规则(文字)
null:转为"null"
undefined:转为"undefined"
布尔类型:true和false分别被转为"true"和"false"
数字类型:转为数字的字符串形式,如10转为"10"
数组:转为以","连接的字符串,空数组[]转为空字符串,数组中的null或undefined,会被当做空字符串处理
普通对象:转为字符串相当于直接使用Object.prototype.toString(),返回"[object Object]"
规则(表格)

ToNumber
作用
将其他类型转换为数字类型
规则(文字)
null: 转为0
undefined:转为NaN
字符串:如果是纯数字形式,则转为对应的数字,空字符转为0, 否则一律按转换失败处理,转为NaN
布尔:true和false被转为1和0
数组:数组先被转为原始类型,然后在根据转换后的原始类型按照上面的规则处理
对象:同数组的处理方式
规则(表格)

ToBoolean
作用
将其他类型转换为布尔类型
规则(文字)
null、undefined、0、NaN、””转为false
其余转为 true
规则(表格)

==运算符规则
比较运算 x==y, 其中 x 和 y 是值,返回 true 或者 false。这样的比较按如下方式进行
1、若 Type(x) 与 Type(y) 相同, 则
1* 若 Type(x) 为 Undefined, 返回 true。
2* 若 Type(x) 为 Null, 返回 true。
3* 若 Type(x) 为 Number, 则
(1)、若 x 为 NaN, 返回 false。
(2)、若 y 为 NaN, 返回 false。
(3)、若 x 与 y 为相等数值, 返回 true。
(4)、若 x 为 +0 且 y 为 −0, 返回 true。
(5)、若 x 为 −0 且 y 为 +0, 返回 true。
(6)、返回 false。
4* 若 Type(x) 为 String, 则当 x 和 y 为完全相同的字符序列(长度相等且相同字符在相同位置)时返回 true。 否则, 返回 false。
5* 若 Type(x) 为 Boolean, 当 x 和 y 为同为 true 或者同为 false 时返回 true。 否则, 返回 false。
6* 当 x 和 y 为引用同一对象时返回 true。否则,返回 false。
2、若 x 为 null 且 y 为 undefined, 返回 true。
3、若 x 为 undefined 且 y 为 null, 返回 true。
4、若 Type(x) 为 Number 且 Type(y) 为 String,返回比较 x == ToNumber(y) 的结果。
5、若 Type(x) 为 String 且 Type(y) 为 Number,返回比较 ToNumber(x) == y 的结果。
6、若 Type(x) 为 Boolean, 返回比较 ToNumber(x) == y 的结果。
7、若 Type(y) 为 Boolean, 返回比较 x == ToNumber(y) 的结果。
8、若 Type(x) 为 String 或 Number,且 Type(y) 为 Object,返回比较 x == ToPrimitive(y) 的结果。
9、若 Type(x) 为 Object 且 Type(y) 为 String 或 Number, 返回比较 ToPrimitive(x) == y 的结果。
10、返回 false。
例题解析
a 为什么值时,控制台能输出Hello world?
a = ? //
if(a == 1 && a == 2 && a == 3){
console.log("Hello world")
}
解法1
利用对象在和原始类型的值比较是默认调用ToPrimitive方法里的ValueOf方法
var a = {
i: 1,
valueOf() {
return this.i++;
}
}
if (a == 1 && a == 2 && a == 3) {
console.log("Hello world");
}
1、在判断a == 1时,因为a为非原始类型,所以需要先调用ToPrimitive方法,调用valueOf方法。
2、返回this.i值为1,并将i自加1,返回的1与等式右边的1进行比较返回true。
3、后面的操作同理
解法2
利用对象在和原始类型的值比较是默认调用ToPrimitive方法里的ToString方法
var a = {
i: 1,
toString() {
return this.i++;
}
}
if (a == 1 && a == 2 && a == 3) {
console.log("Hello world");
}
1、在判断a == 1时,因为a为非原始类型,所以需要先调用ToPrimitive方法,调用valueOf方法,返回自身
2、继续调用toString方法,返回this.i的值为1,并将i自加1,返回的1与等式右边的1进行比较返回true。
3、后面的操作同理
解法3
利用对象在和原始类型的值比较是默认调用ToPrimitive方法里的ToString方法时隐式调用join方法
var a = [1,2,3];
a.join = a.shift;
if (a == 1 && a == 2 && a == 3) {
console.log("Hello world");
}
1、在判断a == 1时,因为a为非原始类型,所以需要先调用ToPrimitive方法,调用valueOf方法,返回自身
2、继续调用toString方法,toString方法默认调用join方法
3、而对象a上的join方法被重写,变成shift方法,因此执行shift方法返回被删除的1,数组变成[2,3]
4、后面的操作同理
其他解法
var val = 0;
Object.defineProperty(window, 'a', {
get: function() {
return ++val;
}
});
// ---------------------------------
let a={
reg: /d/g,
valueOf(){
return this.reg.exec(123)[0]
}
}
最后两个解法不属于隐式转换,所以不再展开
课后习题
null >0 // false
null == 0// false
null >= 0 // true
[] == ![] // true
[] == 0 // true
[2]== 2 // true
['0'] == false // true
'0' == false // true
[] == false // true
[null] == 0 // true
null == 0 // false
[null] == false // true
null == false // false
[undefined] == false // true
undefined == false // false