类型转换
类型转换是指将数据由一种类型变换为另一种类型。在编译器自动赋值时,会发生隐式转换,但在代码中,也可以用一些写法强制要求进行显式转换。例如:在表达式 5 + 2.0 中,整数 5 被隐式转换为浮点数,但 Number(“0x11”) 和 “0x11” 则被显式转换为数字 17。
转Boolean
条件判断时,除了 undefined, null, false, NaN, '', 0, -0,其他所有值都转为 true,包括所有对象。
转对象
对象在转换基本类型时,首先会调用 valueOf 然后调用 toString。
valueOf: 返回指定对象的原始值。toString: 返回一个表示该对象的字符串
// Number
var num = 15.26540;
num.valueOf() // 15.2654
num.toString() // "15.2654"
1 + num // 16.2654
"1" + num // 115.2654
// Array
var array = ["ABC", true, 12, -5];
array.valueOf() // (4) ["ABC", true, 12, -5]
array.toString() // "ABC,true,12,-5"
1 + array // "1ABC,true,12,-5"
array + array //"ABC,true,12,-5ABC,true,12,-5" 注意这里是字符串,而不是数组
// 布尔值
var bool = true;
bool.valueOf() // true
bool.toString() // "true"
1 + bool // 2
bool + bool // 2
"1" + bool // "1true"
// 若布尔值为 false ,转为 number 时的值为 0
var bool = false;
1 + bool // 1
bool + bool // 0
// Function
function foo(){}
foo.valueOf() // ƒ foo(){}
var foo2 = new Function("x", "y", "return x + y;");
foo2.valueOf()
/*
ƒ anonymous(x,y
) {
return x + y;
}
*/
// Object
var obj = {name: "张三", age: 18};
obj.valueOf() // {name: "张三", age: 18}
obj.toString() // "[object Object]"
1 + obj // "1[object Object]"
obj + obj // "[object Object][object Object]"
注意:字符串上下文中的对象通过 toString()方法转换,这与使用valueOf转换为原始字符串的String对象不同。所有对象都能转换成一个“[object 类型]”这种格式的字符串。但是很多对象不能转换为数字,布尔或函数。
重写 valueOf()和toSting
let a = {
valueOf() {
return 0;
},
toString() {
return 'a';
},
}
1 + a // => 1
'1' + a // => '10'
也可以重写 Symbol.toPrimitive ,该方法在转基本类型时调用优先级最高
const obj = {
valueOf() {
return 0;
},
[Symbol.toPrimitive](hint) {
if (hint == 'number') {
return 42;
}else if(hint == 'string'){
return "hello";
}
return true;
}
};
console.log(+obj2); // 42 -- hint 参数值是 "number"
console.log(`${obj2}`); // "hello" -- hint 参数值是 "string"
console.log(obj2 + ""); // "true" -- hint 参数值是 "default"
四则运算符
- 加法运算时:一方是字符串类型,就会把另一个也转为字符串类型。并且加法运算会触发三种类型转换:将值转换为原始值,转换为数字,转换为字符串。
- 其他运算符:一方是数字,那么另一方就转为数字。
若为字符串会转换为数字,转换失败结果会为
NaN
// 一方为数字
1 + '1' // '11'
2 * '2' // 4
4 / '2' // 2
// 都不为数字
'4' / '2' // 2
'2a' * '2' // NaN
['a', 'b'] + ['c', 'd'] // '"a,bc,d",此次为字符串拼接
// 特殊
'a' + + 'b' // -> "aNaN"
// 因为 + '1' -> 1
// + 'b' -> NaN
相等性判断
JavaScript提供三种不同的值比较操作:
- 严格相等 ,类型和值都相等,使用
=== - 宽松相等 ,值相等,使用
== - Object.is (ES6 新特性, 确定两个值是否相同。)
一般而言,所有的对象都与 undefined 和 null 不相等。但是大部分浏览器允许非常窄的一类对象(即,所有页面中的 document.all 对象),在某些情况下,充当效仿 undefined 的角色。
判断x==y,其中x和y都是值
-
若
x和y类型相等x类型为Null,返回truex类型为Undefined,返回truex类型为Number,则x为NaN,返回falsey为NaN,返回falsex为+0且y为-0,返回truex为-0且y为+0,返回truex和y数值相等,返回true- 返回
false
x类型为String,若x和y为完全相同的字符序列,返回true.否则,返回falsex类型为Boolean,同为true或者false时返回true.否则,返回false6.同为引用同一对象时返回true.否则,返回false
-
若
x为null且y为undefined, 返回true。 -
若
x为undefined且y为null, 返回true。 -
若
Type(x)为Number且Type(y)为String,返回comparison x==ToNumber(y)的结果。 -
若
Type(x)为String且Type(y)为Number,.返回比较ToNumber(x)==y的结果。 -
若
Type(x)为Boolean, 返回比较ToNumber(x)== y的结果。 -
若Type(y)为
Boolean,返回比较x ==ToNumber(y)的结果。 -
若
Type(x)为String或Number, 且Type(y)为Object, 返回比较x==ToPrimitive(y)的结果。 -
若
Type(x)为Object且Type(y)为String或Number, 返回比较ToPrimitive(x)==y的结果。返回false。
1 == '1' // true
null = undefined // true
null = document.all // true
undefined = document.all // true
现在来解析一道题目 [] == ![] // -> true ,下面是这个表达式为何为 true 的步骤
// [] 转成 true,然后取反变成 false
[] == false
// 根据第 8 条得出
[] == ToNumber(false)
[] == 0
// 根据第 10 条得出
ToPrimitive([]) == 0
// [].toString() -> ''
'' == 0
// 根据第 6 条得出
0 == 0 // -> true
总结:[] == ! [] -> [] == false -> [] == 0 -> '' == 0 -> 0 == 0 -> true